blob: 1a9507be0c773ab70fe048590a3621321316425e [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
danakj1fd259a02016-04-16 03:17:0910
avibf0746c2015-12-09 19:53:1411#include <limits>
rdsmith1d343be52016-10-21 20:37:5012#include <set>
[email protected]5285d972011-10-18 18:56:3413#include <string>
dchengc7eeda422015-12-26 03:56:4814#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3315#include <vector>
[email protected]77848d12008-11-14 00:00:2216
[email protected]68bf9152008-09-25 19:47:3017#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5218#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2919#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5720#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2421#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4622#include "base/macros.h"
danakj1fd259a02016-04-16 03:17:0923#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4724#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4925#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4726#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0527#include "base/strings/utf_string_conversions.h"
fdorayf33fede2017-05-11 21:18:1028#include "base/test/scoped_task_environment.h"
[email protected]f36a8132011-09-02 18:36:3329#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3530#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3531#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0732#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3333#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0734#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2535#include "net/base/load_timing_info.h"
36#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2437#include "net/base/net_errors.h"
rdsmith1d343be52016-10-21 20:37:5038#include "net/base/network_throttle_manager.h"
tbansal28e68f82016-02-04 02:56:1539#include "net/base/proxy_delegate.h"
[email protected]ac790b42009-12-02 04:31:3140#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5241#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1542#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0643#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2144#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0845#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1146#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1647#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5348#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2449#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1250#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0051#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2952#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1953#include "net/http/http_auth_scheme.h"
Adam Rice425cf122015-01-19 06:18:2454#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5755#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5256#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5657#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2458#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1359#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5360#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5761#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3862#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2463#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1964#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0765#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0066#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1967#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5168#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4669#include "net/log/test_net_log_entry.h"
70#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1371#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5372#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0373#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1174#include "net/proxy/proxy_resolver.h"
xunjieli96f2a402017-06-05 17:24:2775#include "net/proxy/proxy_resolver_factory.h"
tbansal28e68f82016-02-04 02:56:1576#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1177#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4478#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1579#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0380#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4781#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0282#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0783#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4484#include "net/socket/socket_test_util.h"
85#include "net/socket/ssl_client_socket.h"
bnc8f8f7d302017-04-24 18:08:0686#include "net/spdy/chromium/spdy_session.h"
87#include "net/spdy/chromium/spdy_session_pool.h"
88#include "net/spdy/chromium/spdy_test_util_common.h"
89#include "net/spdy/core/spdy_framer.h"
nharperb7441ef2016-01-25 23:54:1490#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5791#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0392#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5793#include "net/ssl/ssl_config_service_defaults.h"
94#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5495#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1196#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0197#include "net/test/gtest_util.h"
fdorayf33fede2017-05-11 21:18:1098#include "net/test/net_test_suite.h"
rsleevia69c79a2016-06-22 03:28:4399#include "net/test/test_data_directory.h"
[email protected]831e4a32013-11-14 02:14:44100#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:18101#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52102#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15103#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27104#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52105
robpercival214763f2016-07-01 23:27:01106using net::test::IsError;
107using net::test::IsOk;
108
[email protected]ad65a3e2013-12-25 18:18:01109using base::ASCIIToUTF16;
110
initial.commit586acc5fe2008-07-26 22:42:52111//-----------------------------------------------------------------------------
112
ttuttle859dc7a2015-04-23 19:42:29113namespace net {
114
[email protected]13c8a092010-07-29 06:15:44115namespace {
116
rdsmith1d343be52016-10-21 20:37:50117class TestNetworkStreamThrottler : public NetworkThrottleManager {
118 public:
119 TestNetworkStreamThrottler()
120 : throttle_new_requests_(false),
121 num_set_priority_calls_(0),
122 last_priority_set_(IDLE) {}
123
124 ~TestNetworkStreamThrottler() override {
125 EXPECT_TRUE(outstanding_throttles_.empty());
126 }
127
128 // NetworkThrottleManager
129 std::unique_ptr<Throttle> CreateThrottle(ThrottleDelegate* delegate,
130 RequestPriority priority,
131 bool ignore_limits) override {
bnc87dcefc2017-05-25 12:47:58132 auto test_throttle =
Jeremy Roman0579ed62017-08-29 15:56:19133 std::make_unique<TestThrottle>(throttle_new_requests_, delegate, this);
rdsmith1d343be52016-10-21 20:37:50134 outstanding_throttles_.insert(test_throttle.get());
135 return std::move(test_throttle);
136 }
137
138 void UnthrottleAllRequests() {
139 std::set<TestThrottle*> outstanding_throttles_copy(outstanding_throttles_);
vmpstr6d9996c82017-02-23 00:43:25140 for (auto* throttle : outstanding_throttles_copy) {
rdsmithbf8c3c12016-11-18 18:16:24141 if (throttle->IsBlocked())
rdsmith1d343be52016-10-21 20:37:50142 throttle->Unthrottle();
143 }
144 }
145
146 void set_throttle_new_requests(bool throttle_new_requests) {
147 throttle_new_requests_ = throttle_new_requests;
148 }
149
150 // Includes both throttled and unthrottled throttles.
151 size_t num_outstanding_requests() const {
152 return outstanding_throttles_.size();
153 }
154
155 int num_set_priority_calls() const { return num_set_priority_calls_; }
156 RequestPriority last_priority_set() const { return last_priority_set_; }
157 void set_priority_change_closure(
158 const base::Closure& priority_change_closure) {
159 priority_change_closure_ = priority_change_closure;
160 }
161
162 private:
163 class TestThrottle : public NetworkThrottleManager::Throttle {
164 public:
165 ~TestThrottle() override { throttler_->OnThrottleDestroyed(this); }
166
167 // Throttle
rdsmithbf8c3c12016-11-18 18:16:24168 bool IsBlocked() const override { return throttled_; }
169 RequestPriority Priority() const override {
170 NOTREACHED();
171 return IDLE;
172 }
rdsmith1d343be52016-10-21 20:37:50173 void SetPriority(RequestPriority priority) override {
174 throttler_->SetPriorityCalled(priority);
175 }
176
177 TestThrottle(bool throttled,
178 ThrottleDelegate* delegate,
179 TestNetworkStreamThrottler* throttler)
180 : throttled_(throttled), delegate_(delegate), throttler_(throttler) {}
181
182 void Unthrottle() {
183 EXPECT_TRUE(throttled_);
184
185 throttled_ = false;
rdsmithbf8c3c12016-11-18 18:16:24186 delegate_->OnThrottleUnblocked(this);
rdsmith1d343be52016-10-21 20:37:50187 }
188
189 bool throttled_;
190 ThrottleDelegate* delegate_;
191 TestNetworkStreamThrottler* throttler_;
192 };
193
194 void OnThrottleDestroyed(TestThrottle* throttle) {
195 EXPECT_NE(0u, outstanding_throttles_.count(throttle));
196 outstanding_throttles_.erase(throttle);
197 }
198
199 void SetPriorityCalled(RequestPriority priority) {
200 ++num_set_priority_calls_;
201 last_priority_set_ = priority;
202 if (!priority_change_closure_.is_null())
203 priority_change_closure_.Run();
204 }
205
206 // Includes both throttled and unthrottled throttles.
207 std::set<TestThrottle*> outstanding_throttles_;
208 bool throttle_new_requests_;
209 int num_set_priority_calls_;
210 RequestPriority last_priority_set_;
211 base::Closure priority_change_closure_;
212
213 DISALLOW_COPY_AND_ASSIGN(TestNetworkStreamThrottler);
214};
215
[email protected]42cba2fb2013-03-29 19:58:57216const base::string16 kBar(ASCIIToUTF16("bar"));
217const base::string16 kBar2(ASCIIToUTF16("bar2"));
218const base::string16 kBar3(ASCIIToUTF16("bar3"));
219const base::string16 kBaz(ASCIIToUTF16("baz"));
220const base::string16 kFirst(ASCIIToUTF16("first"));
221const base::string16 kFoo(ASCIIToUTF16("foo"));
222const base::string16 kFoo2(ASCIIToUTF16("foo2"));
223const base::string16 kFoo3(ASCIIToUTF16("foo3"));
224const base::string16 kFou(ASCIIToUTF16("fou"));
225const base::string16 kSecond(ASCIIToUTF16("second"));
226const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
227const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44228
bnc2df4b522016-07-08 18:17:43229const char kAlternativeServiceHttpHeader[] =
230 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
231
ttuttle859dc7a2015-04-23 19:42:29232int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
233 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
234 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02235}
236
ttuttle859dc7a2015-04-23 19:42:29237int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
238 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
239 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02240}
241
ttuttle859dc7a2015-04-23 19:42:29242bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
243 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
244 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52245}
246
[email protected]f3da152d2012-06-02 01:00:57247// Takes in a Value created from a NetLogHttpResponseParameter, and returns
248// a JSONified list of headers as a single string. Uses single quotes instead
249// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27250bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57251 if (!params)
252 return false;
[email protected]ea5ef4c2013-06-13 22:50:27253 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57254 if (!params->GetList("headers", &header_list))
255 return false;
256 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34257 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28258 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57259 return true;
260}
261
[email protected]029c83b62013-01-24 05:28:20262// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
263// used.
ttuttle859dc7a2015-04-23 19:42:29264void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20265 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19266 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25267
[email protected]029c83b62013-01-24 05:28:20268 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
269 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
270
ttuttle859dc7a2015-04-23 19:42:29271 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20272 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25273
274 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25275
[email protected]3b23a222013-05-15 21:33:25276 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25277 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
278 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25279 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25280}
281
[email protected]029c83b62013-01-24 05:28:20282// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
283// used.
ttuttle859dc7a2015-04-23 19:42:29284void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25285 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20286 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19287 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20288
289 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
290 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
291
ttuttle859dc7a2015-04-23 19:42:29292 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
293 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20294 EXPECT_LE(load_timing_info.connect_timing.connect_end,
295 load_timing_info.send_start);
296
297 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20298
[email protected]3b23a222013-05-15 21:33:25299 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20300 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
301 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25302 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20303}
304
305// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
306// used.
ttuttle859dc7a2015-04-23 19:42:29307void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20308 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19309 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20310
ttuttle859dc7a2015-04-23 19:42:29311 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20312
313 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
314 EXPECT_LE(load_timing_info.proxy_resolve_start,
315 load_timing_info.proxy_resolve_end);
316 EXPECT_LE(load_timing_info.proxy_resolve_end,
317 load_timing_info.send_start);
318 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20319
[email protected]3b23a222013-05-15 21:33:25320 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20321 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
322 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25323 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20324}
325
326// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
327// used.
ttuttle859dc7a2015-04-23 19:42:29328void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20329 int connect_timing_flags) {
330 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19331 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20332
333 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
334 EXPECT_LE(load_timing_info.proxy_resolve_start,
335 load_timing_info.proxy_resolve_end);
336 EXPECT_LE(load_timing_info.proxy_resolve_end,
337 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29338 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
339 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20340 EXPECT_LE(load_timing_info.connect_timing.connect_end,
341 load_timing_info.send_start);
342
343 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20344
[email protected]3b23a222013-05-15 21:33:25345 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20346 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
347 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25348 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25349}
350
ttuttle859dc7a2015-04-23 19:42:29351void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24352 headers->SetHeader("Connection", "Upgrade");
353 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23354 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24355 headers->SetHeader("Sec-WebSocket-Version", "13");
356 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
357}
358
danakj1fd259a02016-04-16 03:17:09359std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42360 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34361 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14362}
363
rdsmith1d343be52016-10-21 20:37:50364// Note that the pointer written into |*throttler| will only be valid
365// for the lifetime of the returned HttpNetworkSession.
366std::unique_ptr<HttpNetworkSession> CreateSessionWithThrottler(
367 SpdySessionDependencies* session_deps,
368 TestNetworkStreamThrottler** throttler) {
369 std::unique_ptr<HttpNetworkSession> session(
370 SpdySessionDependencies::SpdyCreateSession(session_deps));
371
Jeremy Roman0579ed62017-08-29 15:56:19372 auto owned_throttler = std::make_unique<TestNetworkStreamThrottler>();
rdsmith1d343be52016-10-21 20:37:50373 *throttler = owned_throttler.get();
374
375 HttpNetworkSessionPeer peer(session.get());
376 peer.SetNetworkStreamThrottler(std::move(owned_throttler));
377
378 return session;
379}
380
xunjieli96f2a402017-06-05 17:24:27381class FailingProxyResolverFactory : public ProxyResolverFactory {
382 public:
383 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
384
385 // ProxyResolverFactory override.
386 int CreateProxyResolver(
387 const scoped_refptr<ProxyResolverScriptData>& script_data,
388 std::unique_ptr<ProxyResolver>* result,
389 const CompletionCallback& callback,
390 std::unique_ptr<Request>* request) override {
391 return ERR_PAC_SCRIPT_FAILED;
392 }
393};
394
[email protected]448d4ca52012-03-04 04:12:23395} // namespace
396
bncd16676a2016-07-20 16:23:01397class HttpNetworkTransactionTest : public PlatformTest {
[email protected]483fa202013-05-14 01:07:03398 public:
bncd16676a2016-07-20 16:23:01399 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03400 // Important to restore the per-pool limit first, since the pool limit must
401 // always be greater than group limit, and the tests reduce both limits.
402 ClientSocketPoolManager::set_max_sockets_per_pool(
403 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
404 ClientSocketPoolManager::set_max_sockets_per_group(
405 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
406 }
407
[email protected]e3ceb682011-06-28 23:55:46408 protected:
[email protected]23e482282013-06-14 16:08:02409 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15410 : ssl_(ASYNC, OK),
411 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03412 HttpNetworkSession::NORMAL_SOCKET_POOL)),
413 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
414 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28415 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03416 }
[email protected]bb88e1d32013-05-03 23:11:07417
[email protected]e3ceb682011-06-28 23:55:46418 struct SimpleGetHelperResult {
419 int rv;
420 std::string status_line;
421 std::string response_data;
sclittlefb249892015-09-10 21:33:22422 int64_t total_received_bytes;
423 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25424 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47425 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59426 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46427 };
428
dcheng67be2b1f2014-10-27 21:47:29429 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50430 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55431 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54432 }
433
dcheng67be2b1f2014-10-27 21:47:29434 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50435 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55436 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09437 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55438 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09439 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50440 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55441 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09442 }
443
[email protected]202965992011-12-07 23:04:51444 // Either |write_failure| specifies a write failure or |read_failure|
445 // specifies a read failure when using a reused socket. In either case, the
446 // failure should cause the network transaction to resend the request, and the
447 // other argument should be NULL.
448 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
449 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52450
[email protected]a34f61ee2014-03-18 20:59:49451 // Either |write_failure| specifies a write failure or |read_failure|
452 // specifies a read failure when using a reused socket. In either case, the
453 // failure should cause the network transaction to resend the request, and the
454 // other argument should be NULL.
455 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10456 const MockRead* read_failure,
457 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49458
[email protected]5a60c8b2011-10-19 20:14:29459 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
460 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15461 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52462
[email protected]ff007e162009-05-23 09:13:15463 HttpRequestInfo request;
464 request.method = "GET";
bncce36dca22015-04-21 22:11:23465 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:52466
vishal.b62985ca92015-04-17 08:45:51467 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07468 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09469 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16470 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27471
[email protected]5a60c8b2011-10-19 20:14:29472 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07473 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29474 }
initial.commit586acc5fe2008-07-26 22:42:52475
[email protected]49639fa2011-12-20 23:22:41476 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52477
eroman24bc6a12015-05-06 19:55:48478 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16479 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01480 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52481
[email protected]ff007e162009-05-23 09:13:15482 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16483 out.total_received_bytes = trans.GetTotalReceivedBytes();
484 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25485
486 // Even in the failure cases that use this function, connections are always
487 // successfully established before the error.
bnc691fda62016-08-12 00:43:16488 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25489 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
490
[email protected]ff007e162009-05-23 09:13:15491 if (out.rv != OK)
492 return out;
493
bnc691fda62016-08-12 00:43:16494 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50495 // Can't use ASSERT_* inside helper functions like this, so
496 // return an error.
wezca1070932016-05-26 20:30:52497 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50498 out.rv = ERR_UNEXPECTED;
499 return out;
500 }
[email protected]ff007e162009-05-23 09:13:15501 out.status_line = response->headers->GetStatusLine();
502
[email protected]80a09a82012-11-16 17:40:06503 EXPECT_EQ("127.0.0.1", response->socket_address.host());
504 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19505
ttuttled9dbc652015-09-29 20:00:59506 bool got_endpoint =
bnc691fda62016-08-12 00:43:16507 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59508 EXPECT_EQ(got_endpoint,
509 out.remote_endpoint_after_start.address().size() > 0);
510
bnc691fda62016-08-12 00:43:16511 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01512 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40513
mmenke43758e62015-05-04 21:09:46514 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40515 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39516 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00517 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
518 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39519 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00520 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
521 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15522
[email protected]f3da152d2012-06-02 01:00:57523 std::string line;
524 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
525 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
526
[email protected]79e1fd62013-06-20 06:50:04527 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16528 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04529 std::string value;
530 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23531 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04532 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
533 EXPECT_EQ("keep-alive", value);
534
535 std::string response_headers;
536 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23537 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04538 response_headers);
[email protected]3deb9a52010-11-11 00:24:40539
bnc691fda62016-08-12 00:43:16540 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22541 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16542 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22543
bnc691fda62016-08-12 00:43:16544 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47545 return out;
[email protected]ff007e162009-05-23 09:13:15546 }
initial.commit586acc5fe2008-07-26 22:42:52547
[email protected]5a60c8b2011-10-19 20:14:29548 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
549 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22550 MockWrite data_writes[] = {
551 MockWrite("GET / HTTP/1.1\r\n"
552 "Host: www.example.org\r\n"
553 "Connection: keep-alive\r\n\r\n"),
554 };
[email protected]5a60c8b2011-10-19 20:14:29555
sclittlefb249892015-09-10 21:33:22556 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
557 arraysize(data_writes));
558 StaticSocketDataProvider* data[] = {&reads};
559 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
560
561 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
562 out.total_sent_bytes);
563 return out;
[email protected]b8015c42013-12-24 15:18:19564 }
565
bnc032658ba2016-09-26 18:17:15566 void AddSSLSocketData() {
567 ssl_.next_proto = kProtoHTTP2;
568 ssl_.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
569 ASSERT_TRUE(ssl_.cert);
570 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
571 }
572
[email protected]ff007e162009-05-23 09:13:15573 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
574 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52575
[email protected]ff007e162009-05-23 09:13:15576 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07577
578 void BypassHostCacheOnRefreshHelper(int load_flags);
579
580 void CheckErrorIsPassedBack(int error, IoMode mode);
581
[email protected]4bd46222013-05-14 19:32:23582 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07583 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15584 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03585
586 // Original socket limits. Some tests set these. Safest to always restore
587 // them once each test has been run.
588 int old_max_group_sockets_;
589 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15590};
[email protected]231d5a32008-09-13 00:45:27591
[email protected]448d4ca52012-03-04 04:12:23592namespace {
593
ryansturm49a8cb12016-06-15 16:51:09594class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27595 public:
ryansturm49a8cb12016-06-15 16:51:09596 BeforeHeadersSentHandler()
597 : observed_before_headers_sent_with_proxy_(false),
598 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27599
ryansturm49a8cb12016-06-15 16:51:09600 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
601 HttpRequestHeaders* request_headers) {
602 observed_before_headers_sent_ = true;
603 if (!proxy_info.is_http() && !proxy_info.is_https() &&
604 !proxy_info.is_quic()) {
605 return;
606 }
607 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27608 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
609 }
610
ryansturm49a8cb12016-06-15 16:51:09611 bool observed_before_headers_sent_with_proxy() const {
612 return observed_before_headers_sent_with_proxy_;
613 }
614
615 bool observed_before_headers_sent() const {
616 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27617 }
618
619 std::string observed_proxy_server_uri() const {
620 return observed_proxy_server_uri_;
621 }
622
623 private:
ryansturm49a8cb12016-06-15 16:51:09624 bool observed_before_headers_sent_with_proxy_;
625 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27626 std::string observed_proxy_server_uri_;
627
ryansturm49a8cb12016-06-15 16:51:09628 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27629};
630
[email protected]15a5ccf82008-10-23 19:57:43631// Fill |str| with a long header list that consumes >= |size| bytes.
632void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51633 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19634 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
635 const int sizeof_row = strlen(row);
636 const int num_rows = static_cast<int>(
637 ceil(static_cast<float>(size) / sizeof_row));
638 const int sizeof_data = num_rows * sizeof_row;
639 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43640 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51641
[email protected]4ddaf2502008-10-23 18:26:19642 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43643 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19644}
645
thakis84dff942015-07-28 20:47:38646#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29647// Alternative functions that eliminate randomness and dependency on the local
648// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14649void MockGenerateRandom1(uint8_t* output, size_t n) {
650 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
651 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29652 static size_t current_byte = 0;
653 for (size_t i = 0; i < n; ++i) {
654 output[i] = bytes[current_byte++];
655 current_byte %= arraysize(bytes);
656 }
657}
658
avibf0746c2015-12-09 19:53:14659void MockGenerateRandom2(uint8_t* output, size_t n) {
660 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
661 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
662 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29663 static size_t current_byte = 0;
664 for (size_t i = 0; i < n; ++i) {
665 output[i] = bytes[current_byte++];
666 current_byte %= arraysize(bytes);
667 }
668}
669
[email protected]fe2bc6a2009-03-23 16:52:20670std::string MockGetHostName() {
671 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29672}
thakis84dff942015-07-28 20:47:38673#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29674
[email protected]e60e47a2010-07-14 03:37:18675template<typename ParentPool>
676class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31677 public:
[email protected]9e1bdd32011-02-03 21:48:34678 CaptureGroupNameSocketPool(HostResolver* host_resolver,
679 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18680
[email protected]d80a4322009-08-14 07:07:49681 const std::string last_group_name_received() const {
682 return last_group_name_;
683 }
684
dmichaeld6e570d2014-12-18 22:30:57685 int RequestSocket(const std::string& group_name,
686 const void* socket_params,
687 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15688 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57689 ClientSocketHandle* handle,
690 const CompletionCallback& callback,
tfarina42834112016-09-22 13:38:20691 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31692 last_group_name_ = group_name;
693 return ERR_IO_PENDING;
694 }
dmichaeld6e570d2014-12-18 22:30:57695 void CancelRequest(const std::string& group_name,
696 ClientSocketHandle* handle) override {}
697 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09698 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57699 int id) override {}
700 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23701 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57702 int IdleSocketCount() const override { return 0; }
703 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31704 return 0;
705 }
dmichaeld6e570d2014-12-18 22:30:57706 LoadState GetLoadState(const std::string& group_name,
707 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31708 return LOAD_STATE_IDLE;
709 }
dmichaeld6e570d2014-12-18 22:30:57710 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26711 return base::TimeDelta();
712 }
[email protected]d80a4322009-08-14 07:07:49713
714 private:
[email protected]04e5be32009-06-26 20:00:31715 std::string last_group_name_;
716};
717
[email protected]ab739042011-04-07 15:22:28718typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
719CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13720typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
721CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06722typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11723CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18724typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
725CaptureGroupNameSSLSocketPool;
726
rkaplowd90695c2015-03-25 22:12:41727template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18728CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34729 HostResolver* host_resolver,
730 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21731 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18732
hashimoto0d3e4fb2015-01-09 05:02:50733template <>
[email protected]2df19bb2010-08-25 20:13:46734CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21735 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34736 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09737 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46738
[email protected]007b3f82013-04-09 08:46:45739template <>
[email protected]e60e47a2010-07-14 03:37:18740CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21741 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34742 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45743 : SSLClientSocketPool(0,
744 0,
[email protected]007b3f82013-04-09 08:46:45745 cert_verifier,
746 NULL,
747 NULL,
[email protected]284303b62013-11-28 15:11:54748 NULL,
eranm6571b2b2014-12-03 15:53:23749 NULL,
[email protected]007b3f82013-04-09 08:46:45750 std::string(),
751 NULL,
752 NULL,
753 NULL,
754 NULL,
755 NULL,
[email protected]8e458552014-08-05 00:02:15756 NULL) {
757}
[email protected]2227c692010-05-04 15:36:11758
[email protected]231d5a32008-09-13 00:45:27759//-----------------------------------------------------------------------------
760
[email protected]79cb5c12011-09-12 13:12:04761// Helper functions for validating that AuthChallengeInfo's are correctly
762// configured for common cases.
763bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
764 if (!auth_challenge)
765 return false;
766 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43767 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04768 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19769 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04770 return true;
771}
772
773bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
774 if (!auth_challenge)
775 return false;
776 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43777 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
778 EXPECT_EQ("MyRealm1", auth_challenge->realm);
779 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
780 return true;
781}
782
783bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
784 if (!auth_challenge)
785 return false;
786 EXPECT_TRUE(auth_challenge->is_proxy);
787 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04788 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19789 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04790 return true;
791}
792
793bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
794 if (!auth_challenge)
795 return false;
796 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43797 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04798 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19799 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04800 return true;
801}
802
thakis84dff942015-07-28 20:47:38803#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04804bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
805 if (!auth_challenge)
806 return false;
807 EXPECT_FALSE(auth_challenge->is_proxy);
Bence Béky83eb3512017-09-05 12:56:09808 EXPECT_EQ("https://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04809 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19810 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04811 return true;
812}
thakis84dff942015-07-28 20:47:38813#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04814
[email protected]448d4ca52012-03-04 04:12:23815} // namespace
816
bncd16676a2016-07-20 16:23:01817TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09818 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16819 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27820}
821
bncd16676a2016-07-20 16:23:01822TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27823 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35824 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
825 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06826 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27827 };
[email protected]31a2bfe2010-02-09 08:03:39828 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
829 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01830 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27831 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
832 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22833 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
834 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47835 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59836
837 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27838}
839
840// Response with no status line.
bncd16676a2016-07-20 16:23:01841TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27842 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35843 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06844 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27845 };
[email protected]31a2bfe2010-02-09 08:03:39846 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
847 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41848 EXPECT_THAT(out.rv, IsOk());
849 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
850 EXPECT_EQ("hello world", out.response_data);
851 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
852 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27853}
854
mmenkea7da6da2016-09-01 21:56:52855// Response with no status line, and a weird port. Should fail by default.
856TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
857 MockRead data_reads[] = {
858 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
859 };
860
861 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
862 session_deps_.socket_factory->AddSocketDataProvider(&data);
863
864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
865
krasinc06a72a2016-12-21 03:42:46866 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58867 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19868 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52869
mmenkea7da6da2016-09-01 21:56:52870 request.method = "GET";
871 request.url = GURL("http://www.example.com:2000/");
872 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20873 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52874 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
875}
876
877// Response with no status line, and a weird port. Option to allow weird ports
878// enabled.
879TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
880 MockRead data_reads[] = {
881 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
882 };
883
884 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
885 session_deps_.socket_factory->AddSocketDataProvider(&data);
886 session_deps_.http_09_on_non_default_ports_enabled = true;
887 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
888
krasinc06a72a2016-12-21 03:42:46889 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58890 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19891 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52892
mmenkea7da6da2016-09-01 21:56:52893 request.method = "GET";
894 request.url = GURL("http://www.example.com:2000/");
895 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20896 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52897 EXPECT_THAT(callback.GetResult(rv), IsOk());
898
899 const HttpResponseInfo* info = trans->GetResponseInfo();
900 ASSERT_TRUE(info->headers);
901 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
902
903 // Don't bother to read the body - that's verified elsewhere, important thing
904 // is that the option to allow HTTP/0.9 on non-default ports is respected.
905}
906
[email protected]231d5a32008-09-13 00:45:27907// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01908TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27909 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35910 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06911 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27912 };
[email protected]31a2bfe2010-02-09 08:03:39913 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
914 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01915 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27916 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
917 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22918 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
919 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27920}
921
922// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01923TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27924 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35925 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06926 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27927 };
[email protected]31a2bfe2010-02-09 08:03:39928 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
929 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01930 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27931 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
932 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22933 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
934 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27935}
936
937// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01938TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27939 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35940 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06941 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27942 };
[email protected]31a2bfe2010-02-09 08:03:39943 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
944 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41945 EXPECT_THAT(out.rv, IsOk());
946 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
947 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
948 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
949 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27950}
951
952// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01953TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27954 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35955 MockRead("\n"),
956 MockRead("\n"),
957 MockRead("Q"),
958 MockRead("J"),
959 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06960 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27961 };
[email protected]31a2bfe2010-02-09 08:03:39962 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
963 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01964 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27965 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
966 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22967 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
968 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27969}
970
971// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01972TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27973 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35974 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06975 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27976 };
[email protected]31a2bfe2010-02-09 08:03:39977 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
978 arraysize(data_reads));
mmenkea2dcd3bf2016-08-16 21:49:41979 EXPECT_THAT(out.rv, IsOk());
980 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
981 EXPECT_EQ("HTT", out.response_data);
982 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
983 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52984}
985
[email protected]f9d44aa2008-09-23 23:57:17986// Simulate a 204 response, lacking a Content-Length header, sent over a
987// persistent connection. The response should still terminate since a 204
988// cannot have a response body.
bncd16676a2016-07-20 16:23:01989TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19990 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17991 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35992 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19993 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06994 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17995 };
[email protected]31a2bfe2010-02-09 08:03:39996 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
997 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:01998 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17999 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1000 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:221001 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1002 int64_t response_size = reads_size - strlen(junk);
1003 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171004}
1005
[email protected]0877e3d2009-10-17 22:29:571006// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011007TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191008 std::string final_chunk = "0\r\n\r\n";
1009 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1010 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571011 MockRead data_reads[] = {
1012 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1013 MockRead("5\r\nHello\r\n"),
1014 MockRead("1\r\n"),
1015 MockRead(" \r\n"),
1016 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191017 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061018 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571019 };
[email protected]31a2bfe2010-02-09 08:03:391020 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1021 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011022 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571023 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1024 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:221025 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
1026 int64_t response_size = reads_size - extra_data.size();
1027 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571028}
1029
[email protected]9fe44f52010-09-23 18:36:001030// Next tests deal with http://crbug.com/56344.
1031
bncd16676a2016-07-20 16:23:011032TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001033 MultipleContentLengthHeadersNoTransferEncoding) {
1034 MockRead data_reads[] = {
1035 MockRead("HTTP/1.1 200 OK\r\n"),
1036 MockRead("Content-Length: 10\r\n"),
1037 MockRead("Content-Length: 5\r\n\r\n"),
1038 };
1039 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1040 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011041 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001042}
1043
bncd16676a2016-07-20 16:23:011044TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041045 DuplicateContentLengthHeadersNoTransferEncoding) {
1046 MockRead data_reads[] = {
1047 MockRead("HTTP/1.1 200 OK\r\n"),
1048 MockRead("Content-Length: 5\r\n"),
1049 MockRead("Content-Length: 5\r\n\r\n"),
1050 MockRead("Hello"),
1051 };
1052 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1053 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011054 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041055 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1056 EXPECT_EQ("Hello", out.response_data);
1057}
1058
bncd16676a2016-07-20 16:23:011059TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041060 ComplexContentLengthHeadersNoTransferEncoding) {
1061 // More than 2 dupes.
1062 {
1063 MockRead data_reads[] = {
1064 MockRead("HTTP/1.1 200 OK\r\n"),
1065 MockRead("Content-Length: 5\r\n"),
1066 MockRead("Content-Length: 5\r\n"),
1067 MockRead("Content-Length: 5\r\n\r\n"),
1068 MockRead("Hello"),
1069 };
1070 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1071 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011072 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041073 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1074 EXPECT_EQ("Hello", out.response_data);
1075 }
1076 // HTTP/1.0
1077 {
1078 MockRead data_reads[] = {
1079 MockRead("HTTP/1.0 200 OK\r\n"),
1080 MockRead("Content-Length: 5\r\n"),
1081 MockRead("Content-Length: 5\r\n"),
1082 MockRead("Content-Length: 5\r\n\r\n"),
1083 MockRead("Hello"),
1084 };
1085 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1086 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011087 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041088 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1089 EXPECT_EQ("Hello", out.response_data);
1090 }
1091 // 2 dupes and one mismatched.
1092 {
1093 MockRead data_reads[] = {
1094 MockRead("HTTP/1.1 200 OK\r\n"),
1095 MockRead("Content-Length: 10\r\n"),
1096 MockRead("Content-Length: 10\r\n"),
1097 MockRead("Content-Length: 5\r\n\r\n"),
1098 };
1099 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1100 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011101 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041102 }
1103}
1104
bncd16676a2016-07-20 16:23:011105TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001106 MultipleContentLengthHeadersTransferEncoding) {
1107 MockRead data_reads[] = {
1108 MockRead("HTTP/1.1 200 OK\r\n"),
1109 MockRead("Content-Length: 666\r\n"),
1110 MockRead("Content-Length: 1337\r\n"),
1111 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1112 MockRead("5\r\nHello\r\n"),
1113 MockRead("1\r\n"),
1114 MockRead(" \r\n"),
1115 MockRead("5\r\nworld\r\n"),
1116 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061117 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001118 };
1119 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1120 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011121 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001122 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1123 EXPECT_EQ("Hello world", out.response_data);
1124}
1125
[email protected]1628fe92011-10-04 23:04:551126// Next tests deal with http://crbug.com/98895.
1127
1128// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011129TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551130 MockRead data_reads[] = {
1131 MockRead("HTTP/1.1 200 OK\r\n"),
1132 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1133 MockRead("Content-Length: 5\r\n\r\n"),
1134 MockRead("Hello"),
1135 };
1136 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1137 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011138 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551139 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1140 EXPECT_EQ("Hello", out.response_data);
1141}
1142
[email protected]54a9c6e52012-03-21 20:10:591143// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011144TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551145 MockRead data_reads[] = {
1146 MockRead("HTTP/1.1 200 OK\r\n"),
1147 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1148 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1149 MockRead("Content-Length: 5\r\n\r\n"),
1150 MockRead("Hello"),
1151 };
1152 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1153 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011154 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591155 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1156 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551157}
1158
1159// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011160TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551161 MockRead data_reads[] = {
1162 MockRead("HTTP/1.1 200 OK\r\n"),
1163 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1164 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1165 MockRead("Content-Length: 5\r\n\r\n"),
1166 MockRead("Hello"),
1167 };
1168 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1169 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011170 EXPECT_THAT(out.rv,
1171 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551172}
1173
[email protected]54a9c6e52012-03-21 20:10:591174// Checks that two identical Location headers result in no error.
1175// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011176TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551177 MockRead data_reads[] = {
1178 MockRead("HTTP/1.1 302 Redirect\r\n"),
1179 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591180 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551181 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061182 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551183 };
1184
1185 HttpRequestInfo request;
1186 request.method = "GET";
1187 request.url = GURL("http://redirect.com/");
[email protected]1628fe92011-10-04 23:04:551188
danakj1fd259a02016-04-16 03:17:091189 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161190 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551191
1192 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071193 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551194
[email protected]49639fa2011-12-20 23:22:411195 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551196
tfarina42834112016-09-22 13:38:201197 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011198 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551199
robpercival214763f2016-07-01 23:27:011200 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551201
bnc691fda62016-08-12 00:43:161202 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521203 ASSERT_TRUE(response);
1204 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551205 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1206 std::string url;
1207 EXPECT_TRUE(response->headers->IsRedirect(&url));
1208 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471209 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551210}
1211
[email protected]1628fe92011-10-04 23:04:551212// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011213TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551214 MockRead data_reads[] = {
1215 MockRead("HTTP/1.1 302 Redirect\r\n"),
1216 MockRead("Location: http://good.com/\r\n"),
1217 MockRead("Location: http://evil.com/\r\n"),
1218 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061219 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551220 };
1221 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1222 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011223 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551224}
1225
[email protected]ef0faf2e72009-03-05 23:27:231226// Do a request using the HEAD method. Verify that we don't try to read the
1227// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011228TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421229 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231230 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231231 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231232
danakj1fd259a02016-04-16 03:17:091233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161234 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091235 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161236 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091237 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1238 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271239
[email protected]ef0faf2e72009-03-05 23:27:231240 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131241 MockWrite("HEAD / HTTP/1.1\r\n"
1242 "Host: www.example.org\r\n"
1243 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231244 };
1245 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231246 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1247 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231248
mmenked39192ee2015-12-09 00:57:231249 // No response body because the test stops reading here.
1250 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231251 };
1252
[email protected]31a2bfe2010-02-09 08:03:391253 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1254 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071255 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231256
[email protected]49639fa2011-12-20 23:22:411257 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231258
tfarina42834112016-09-22 13:38:201259 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011260 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231261
1262 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011263 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231264
bnc691fda62016-08-12 00:43:161265 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521266 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231267
1268 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521269 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231270 EXPECT_EQ(1234, response->headers->GetContentLength());
1271 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471272 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091273 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1274 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231275
1276 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101277 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231278 bool has_server_header = response->headers->EnumerateHeader(
1279 &iter, "Server", &server_header);
1280 EXPECT_TRUE(has_server_header);
1281 EXPECT_EQ("Blah", server_header);
1282
1283 // Reading should give EOF right away, since there is no message body
1284 // (despite non-zero content-length).
1285 std::string response_data;
bnc691fda62016-08-12 00:43:161286 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011287 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231288 EXPECT_EQ("", response_data);
1289}
1290
bncd16676a2016-07-20 16:23:011291TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091292 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521293
1294 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351295 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1296 MockRead("hello"),
1297 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1298 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061299 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521300 };
[email protected]31a2bfe2010-02-09 08:03:391301 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071302 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521303
[email protected]0b0bf032010-09-21 18:08:501304 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521305 "hello", "world"
1306 };
1307
1308 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421309 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521310 request.method = "GET";
bncce36dca22015-04-21 22:11:231311 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521312
bnc691fda62016-08-12 00:43:161313 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271314
[email protected]49639fa2011-12-20 23:22:411315 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521316
tfarina42834112016-09-22 13:38:201317 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011318 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521319
1320 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011321 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521322
bnc691fda62016-08-12 00:43:161323 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521324 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521325
wezca1070932016-05-26 20:30:521326 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251327 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471328 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521329
1330 std::string response_data;
bnc691fda62016-08-12 00:43:161331 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011332 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251333 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521334 }
1335}
1336
bncd16676a2016-07-20 16:23:011337TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091338 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221339 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191340 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221341 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271342
[email protected]1c773ea12009-04-28 19:58:421343 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521344 request.method = "POST";
1345 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271346 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521347
shivanishab9a143952016-09-19 17:23:411348 // Check the upload progress returned before initialization is correct.
1349 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1350 EXPECT_EQ(0u, progress.size());
1351 EXPECT_EQ(0u, progress.position());
1352
danakj1fd259a02016-04-16 03:17:091353 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271355
initial.commit586acc5fe2008-07-26 22:42:521356 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351357 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1358 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1359 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061360 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521361 };
[email protected]31a2bfe2010-02-09 08:03:391362 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071363 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521364
[email protected]49639fa2011-12-20 23:22:411365 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521366
tfarina42834112016-09-22 13:38:201367 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521369
1370 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011371 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521372
bnc691fda62016-08-12 00:43:161373 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521374 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521375
wezca1070932016-05-26 20:30:521376 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251377 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521378
1379 std::string response_data;
bnc691fda62016-08-12 00:43:161380 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011381 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251382 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521383}
1384
[email protected]3a2d3662009-03-27 03:49:141385// This test is almost the same as Ignores100 above, but the response contains
1386// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571387// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011388TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421389 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141390 request.method = "GET";
1391 request.url = GURL("http://www.foo.com/");
[email protected]3a2d3662009-03-27 03:49:141392
danakj1fd259a02016-04-16 03:17:091393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271395
[email protected]3a2d3662009-03-27 03:49:141396 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571397 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1398 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141399 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061400 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141401 };
[email protected]31a2bfe2010-02-09 08:03:391402 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071403 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141404
[email protected]49639fa2011-12-20 23:22:411405 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141406
tfarina42834112016-09-22 13:38:201407 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011408 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141409
1410 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011411 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141412
bnc691fda62016-08-12 00:43:161413 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521414 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141415
wezca1070932016-05-26 20:30:521416 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141417 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1418
1419 std::string response_data;
bnc691fda62016-08-12 00:43:161420 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011421 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141422 EXPECT_EQ("hello world", response_data);
1423}
1424
bncd16676a2016-07-20 16:23:011425TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081426 HttpRequestInfo request;
1427 request.method = "POST";
1428 request.url = GURL("http://www.foo.com/");
zmo9528c9f42015-08-04 22:12:081429
danakj1fd259a02016-04-16 03:17:091430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161431 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081432
1433 MockRead data_reads[] = {
1434 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1435 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381436 };
zmo9528c9f42015-08-04 22:12:081437 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1438 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381439
zmo9528c9f42015-08-04 22:12:081440 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381441
tfarina42834112016-09-22 13:38:201442 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011443 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381444
zmo9528c9f42015-08-04 22:12:081445 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011446 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381447
zmo9528c9f42015-08-04 22:12:081448 std::string response_data;
bnc691fda62016-08-12 00:43:161449 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011450 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081451 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381452}
1453
bncd16676a2016-07-20 16:23:011454TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381455 HttpRequestInfo request;
1456 request.method = "POST";
1457 request.url = GURL("http://www.foo.com/");
[email protected]ee9410e72010-01-07 01:42:381458
danakj1fd259a02016-04-16 03:17:091459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161460 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271461
[email protected]ee9410e72010-01-07 01:42:381462 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061463 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381464 };
[email protected]31a2bfe2010-02-09 08:03:391465 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071466 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381467
[email protected]49639fa2011-12-20 23:22:411468 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381469
tfarina42834112016-09-22 13:38:201470 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011471 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381472
1473 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011474 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381475}
1476
[email protected]23e482282013-06-14 16:08:021477void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511478 const MockWrite* write_failure,
1479 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421480 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521481 request.method = "GET";
1482 request.url = GURL("http://www.foo.com/");
initial.commit586acc5fe2008-07-26 22:42:521483
vishal.b62985ca92015-04-17 08:45:511484 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071485 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091486 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271487
[email protected]202965992011-12-07 23:04:511488 // Written data for successfully sending both requests.
1489 MockWrite data1_writes[] = {
1490 MockWrite("GET / HTTP/1.1\r\n"
1491 "Host: www.foo.com\r\n"
1492 "Connection: keep-alive\r\n\r\n"),
1493 MockWrite("GET / HTTP/1.1\r\n"
1494 "Host: www.foo.com\r\n"
1495 "Connection: keep-alive\r\n\r\n")
1496 };
1497
1498 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521499 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351500 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1501 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061502 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521503 };
[email protected]202965992011-12-07 23:04:511504
1505 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491506 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511507 data1_writes[1] = *write_failure;
1508 } else {
1509 ASSERT_TRUE(read_failure);
1510 data1_reads[2] = *read_failure;
1511 }
1512
1513 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1514 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071515 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521516
1517 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351518 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1519 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061520 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521521 };
[email protected]31a2bfe2010-02-09 08:03:391522 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071523 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521524
thestig9d3bb0c2015-01-24 00:49:511525 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521526 "hello", "world"
1527 };
1528
mikecironef22f9812016-10-04 03:40:191529 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521530 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411531 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521532
bnc691fda62016-08-12 00:43:161533 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521534
tfarina42834112016-09-22 13:38:201535 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011536 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521537
1538 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011539 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521540
[email protected]58e32bb2013-01-21 18:23:251541 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161542 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251543 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1544 if (i == 0) {
1545 first_socket_log_id = load_timing_info.socket_log_id;
1546 } else {
1547 // The second request should be using a new socket.
1548 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1549 }
1550
bnc691fda62016-08-12 00:43:161551 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521552 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521553
wezca1070932016-05-26 20:30:521554 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471555 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251556 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521557
1558 std::string response_data;
bnc691fda62016-08-12 00:43:161559 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011560 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251561 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521562 }
1563}
[email protected]3d2a59b2008-09-26 19:44:251564
[email protected]a34f61ee2014-03-18 20:59:491565void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1566 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101567 const MockRead* read_failure,
1568 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491569 HttpRequestInfo request;
1570 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101571 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491572
vishal.b62985ca92015-04-17 08:45:511573 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491574 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091575 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491576
[email protected]09356c652014-03-25 15:36:101577 SSLSocketDataProvider ssl1(ASYNC, OK);
1578 SSLSocketDataProvider ssl2(ASYNC, OK);
1579 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361580 ssl1.next_proto = kProtoHTTP2;
1581 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101582 }
1583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1584 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491585
[email protected]09356c652014-03-25 15:36:101586 // SPDY versions of the request and response.
bncdf80d44fd2016-07-15 20:27:411587 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491588 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncdf80d44fd2016-07-15 20:27:411589 SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151590 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:411591 SpdySerializedFrame spdy_data(
1592 spdy_util_.ConstructSpdyDataFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491593
[email protected]09356c652014-03-25 15:36:101594 // HTTP/1.1 versions of the request and response.
1595 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1596 "Host: www.foo.com\r\n"
1597 "Connection: keep-alive\r\n\r\n";
1598 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1599 const char kHttpData[] = "hello";
1600
1601 std::vector<MockRead> data1_reads;
1602 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491603 if (write_failure) {
1604 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101605 data1_writes.push_back(*write_failure);
1606 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491607 } else {
1608 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101609 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411610 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101611 } else {
1612 data1_writes.push_back(MockWrite(kHttpRequest));
1613 }
1614 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491615 }
1616
[email protected]09356c652014-03-25 15:36:101617 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1618 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491619 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1620
[email protected]09356c652014-03-25 15:36:101621 std::vector<MockRead> data2_reads;
1622 std::vector<MockWrite> data2_writes;
1623
1624 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411625 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101626
bncdf80d44fd2016-07-15 20:27:411627 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1628 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101629 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1630 } else {
1631 data2_writes.push_back(
1632 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1633
1634 data2_reads.push_back(
1635 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1636 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1637 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1638 }
rch8e6c6c42015-05-01 14:05:131639 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1640 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491641 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1642
1643 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591644 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491645 // Wait for the preconnect to complete.
1646 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1647 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101648 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491649
1650 // Make the request.
1651 TestCompletionCallback callback;
1652
bnc691fda62016-08-12 00:43:161653 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491654
tfarina42834112016-09-22 13:38:201655 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491657
1658 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011659 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491660
1661 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161662 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101663 TestLoadTimingNotReused(
1664 load_timing_info,
1665 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491666
bnc691fda62016-08-12 00:43:161667 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521668 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491669
wezca1070932016-05-26 20:30:521670 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021671 if (response->was_fetched_via_spdy) {
1672 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1673 } else {
1674 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1675 }
[email protected]a34f61ee2014-03-18 20:59:491676
1677 std::string response_data;
bnc691fda62016-08-12 00:43:161678 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011679 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101680 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491681}
1682
Biljith Jayan45a41722017-08-16 18:43:141683// Test that we do not retry indefinitely when a server sends an error like
1684// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1685// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1686TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1687 HttpRequestInfo request;
1688 request.method = "GET";
1689 request.url = GURL("https://www.foo.com/");
1690
1691 // Check whether we give up after the third try.
1692
1693 // Construct an HTTP2 request and a "Go away" response.
1694 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1695 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1696 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1697 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1698 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1699
1700 // Three go away responses.
1701 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1702 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1703 StaticSocketDataProvider data3(&data_read1, 1, &data_write, 1);
1704
1705 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1706 AddSSLSocketData();
1707 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1708 AddSSLSocketData();
1709 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1710 AddSSLSocketData();
1711
1712 TestCompletionCallback callback;
1713 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1715
1716 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1717 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1718
1719 rv = callback.WaitForResult();
1720 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1721}
1722
1723TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1724 HttpRequestInfo request;
1725 request.method = "GET";
1726 request.url = GURL("https://www.foo.com/");
1727
1728 // Check whether we try atleast thrice before giving up.
1729
1730 // Construct an HTTP2 request and a "Go away" response.
1731 SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
1732 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
1733 SpdySerializedFrame spdy_response_go_away(spdy_util_.ConstructSpdyGoAway());
1734 MockRead data_read1 = CreateMockRead(spdy_response_go_away);
1735 MockWrite data_write = CreateMockWrite(spdy_request, 0);
1736
1737 // Construct a non error HTTP2 response.
1738 SpdySerializedFrame spdy_response_no_error(
1739 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1740 SpdySerializedFrame spdy_data(spdy_util_.ConstructSpdyDataFrame(1, true));
1741 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1742 CreateMockRead(spdy_data, 2)};
1743
1744 // Two error responses.
1745 StaticSocketDataProvider data1(&data_read1, 1, &data_write, 1);
1746 StaticSocketDataProvider data2(&data_read1, 1, &data_write, 1);
1747 // Followed by a success response.
1748 SequencedSocketData data3(data_read2, 2, &data_write, 1);
1749
1750 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1751 AddSSLSocketData();
1752 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1753 AddSSLSocketData();
1754 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1755 AddSSLSocketData();
1756
1757 TestCompletionCallback callback;
1758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1759 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1760
1761 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1762 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1763
1764 rv = callback.WaitForResult();
1765 EXPECT_THAT(rv, IsOk());
1766}
1767
bncd16676a2016-07-20 16:23:011768TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061769 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511770 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1771}
1772
bncd16676a2016-07-20 16:23:011773TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061774 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511775 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251776}
1777
bncd16676a2016-07-20 16:23:011778TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061779 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511780 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251781}
1782
[email protected]d58ceea82014-06-04 10:55:541783// Make sure that on a 408 response (Request Timeout), the request is retried,
1784// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011785TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541786 MockRead read_failure(SYNCHRONOUS,
1787 "HTTP/1.1 408 Request Timeout\r\n"
1788 "Connection: Keep-Alive\r\n"
1789 "Content-Length: 6\r\n\r\n"
1790 "Pickle");
1791 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1792}
1793
bncd16676a2016-07-20 16:23:011794TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491795 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101796 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491797}
1798
bncd16676a2016-07-20 16:23:011799TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491800 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101801 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491802}
1803
bncd16676a2016-07-20 16:23:011804TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491805 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101806 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1807}
1808
bncd16676a2016-07-20 16:23:011809TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101810 MockRead read_failure(ASYNC, OK); // EOF
1811 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1812}
1813
[email protected]d58ceea82014-06-04 10:55:541814// Make sure that on a 408 response (Request Timeout), the request is retried,
1815// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011816TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541817 MockRead read_failure(SYNCHRONOUS,
1818 "HTTP/1.1 408 Request Timeout\r\n"
1819 "Connection: Keep-Alive\r\n"
1820 "Content-Length: 6\r\n\r\n"
1821 "Pickle");
1822 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1823 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1824}
1825
bncd16676a2016-07-20 16:23:011826TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101827 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1828 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1829}
1830
bncd16676a2016-07-20 16:23:011831TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101832 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1833 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1834}
1835
bncd16676a2016-07-20 16:23:011836TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101837 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1838 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1839}
1840
bncd16676a2016-07-20 16:23:011841TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101842 MockRead read_failure(ASYNC, OK); // EOF
1843 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491844}
1845
bncd16676a2016-07-20 16:23:011846TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421847 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251848 request.method = "GET";
bncce36dca22015-04-21 22:11:231849 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251850
danakj1fd259a02016-04-16 03:17:091851 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161852 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271853
[email protected]3d2a59b2008-09-26 19:44:251854 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061855 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351856 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1857 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061858 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251859 };
[email protected]31a2bfe2010-02-09 08:03:391860 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071861 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251862
[email protected]49639fa2011-12-20 23:22:411863 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251864
tfarina42834112016-09-22 13:38:201865 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011866 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251867
1868 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011869 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591870
1871 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161872 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591873 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251874}
1875
1876// What do various browsers do when the server closes a non-keepalive
1877// connection without sending any response header or body?
1878//
1879// IE7: error page
1880// Safari 3.1.2 (Windows): error page
1881// Firefox 3.0.1: blank page
1882// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421883// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1884// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011885TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251886 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061887 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351888 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1889 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061890 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251891 };
[email protected]31a2bfe2010-02-09 08:03:391892 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1893 arraysize(data_reads));
robpercival214763f2016-07-01 23:27:011894 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251895}
[email protected]1826a402014-01-08 15:40:481896
[email protected]7a5378b2012-11-04 03:25:171897// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1898// tests. There was a bug causing HttpNetworkTransaction to hang in the
1899// destructor in such situations.
1900// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011901TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171902 HttpRequestInfo request;
1903 request.method = "GET";
bncce36dca22015-04-21 22:11:231904 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171905
danakj1fd259a02016-04-16 03:17:091906 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581907 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191908 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171909
1910 MockRead data_reads[] = {
1911 MockRead("HTTP/1.0 200 OK\r\n"),
1912 MockRead("Connection: keep-alive\r\n"),
1913 MockRead("Content-Length: 100\r\n\r\n"),
1914 MockRead("hello"),
1915 MockRead(SYNCHRONOUS, 0),
1916 };
1917 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071918 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171919
1920 TestCompletionCallback callback;
1921
tfarina42834112016-09-22 13:38:201922 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171924
1925 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011926 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171927
1928 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501929 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171930 if (rv == ERR_IO_PENDING)
1931 rv = callback.WaitForResult();
1932 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501933 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011934 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171935
1936 trans.reset();
fdoray92e35a72016-06-10 15:54:551937 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171938 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1939}
1940
bncd16676a2016-07-20 16:23:011941TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171942 HttpRequestInfo request;
1943 request.method = "GET";
bncce36dca22015-04-21 22:11:231944 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171945
danakj1fd259a02016-04-16 03:17:091946 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581947 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191948 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171949
1950 MockRead data_reads[] = {
1951 MockRead("HTTP/1.0 200 OK\r\n"),
1952 MockRead("Connection: keep-alive\r\n"),
1953 MockRead("Content-Length: 100\r\n\r\n"),
1954 MockRead(SYNCHRONOUS, 0),
1955 };
1956 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071957 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171958
1959 TestCompletionCallback callback;
1960
tfarina42834112016-09-22 13:38:201961 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171963
1964 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011965 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171966
1967 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501968 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171969 if (rv == ERR_IO_PENDING)
1970 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011971 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171972
1973 trans.reset();
fdoray92e35a72016-06-10 15:54:551974 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171975 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1976}
1977
[email protected]0b0bf032010-09-21 18:08:501978// Test that we correctly reuse a keep-alive connection after not explicitly
1979// reading the body.
bncd16676a2016-07-20 16:23:011980TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131981 HttpRequestInfo request;
1982 request.method = "GET";
1983 request.url = GURL("http://www.foo.com/");
[email protected]fc31d6a42010-06-24 18:05:131984
vishal.b62985ca92015-04-17 08:45:511985 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071986 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271988
mmenkecc2298e2015-12-07 18:20:181989 const char* request_data =
1990 "GET / HTTP/1.1\r\n"
1991 "Host: www.foo.com\r\n"
1992 "Connection: keep-alive\r\n\r\n";
1993 MockWrite data_writes[] = {
1994 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1995 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1996 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1997 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1998 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1999 };
2000
[email protected]0b0bf032010-09-21 18:08:502001 // Note that because all these reads happen in the same
2002 // StaticSocketDataProvider, it shows that the same socket is being reused for
2003 // all transactions.
mmenkecc2298e2015-12-07 18:20:182004 MockRead data_reads[] = {
2005 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2006 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2007 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2008 MockRead(ASYNC, 7,
2009 "HTTP/1.1 302 Found\r\n"
2010 "Content-Length: 0\r\n\r\n"),
2011 MockRead(ASYNC, 9,
2012 "HTTP/1.1 302 Found\r\n"
2013 "Content-Length: 5\r\n\r\n"
2014 "hello"),
2015 MockRead(ASYNC, 11,
2016 "HTTP/1.1 301 Moved Permanently\r\n"
2017 "Content-Length: 0\r\n\r\n"),
2018 MockRead(ASYNC, 13,
2019 "HTTP/1.1 301 Moved Permanently\r\n"
2020 "Content-Length: 5\r\n\r\n"
2021 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132022
mmenkecc2298e2015-12-07 18:20:182023 // In the next two rounds, IsConnectedAndIdle returns false, due to
2024 // the set_busy_before_sync_reads(true) call, while the
2025 // HttpNetworkTransaction is being shut down, but the socket is still
2026 // reuseable. See http://crbug.com/544255.
2027 MockRead(ASYNC, 15,
2028 "HTTP/1.1 200 Hunky-Dory\r\n"
2029 "Content-Length: 5\r\n\r\n"),
2030 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132031
mmenkecc2298e2015-12-07 18:20:182032 MockRead(ASYNC, 18,
2033 "HTTP/1.1 200 Hunky-Dory\r\n"
2034 "Content-Length: 5\r\n\r\n"
2035 "he"),
2036 MockRead(SYNCHRONOUS, 19, "llo"),
2037
2038 // The body of the final request is actually read.
2039 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2040 MockRead(ASYNC, 22, "hello"),
2041 };
2042 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2043 arraysize(data_writes));
2044 data.set_busy_before_sync_reads(true);
2045 session_deps_.socket_factory->AddSocketDataProvider(&data);
2046
2047 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502048 std::string response_lines[kNumUnreadBodies];
2049
mikecironef22f9812016-10-04 03:40:192050 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182051 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412052 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132053
Jeremy Roman0579ed62017-08-29 15:56:192054 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582055 session.get());
[email protected]fc31d6a42010-06-24 18:05:132056
tfarina42834112016-09-22 13:38:202057 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012058 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132059
[email protected]58e32bb2013-01-21 18:23:252060 LoadTimingInfo load_timing_info;
2061 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2062 if (i == 0) {
2063 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2064 first_socket_log_id = load_timing_info.socket_log_id;
2065 } else {
2066 TestLoadTimingReused(load_timing_info);
2067 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2068 }
2069
[email protected]fc31d6a42010-06-24 18:05:132070 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182071 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132072
mmenkecc2298e2015-12-07 18:20:182073 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502074 response_lines[i] = response->headers->GetStatusLine();
2075
mmenkecc2298e2015-12-07 18:20:182076 // Delete the transaction without reading the response bodies. Then spin
2077 // the message loop, so the response bodies are drained.
2078 trans.reset();
2079 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132080 }
[email protected]0b0bf032010-09-21 18:08:502081
2082 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182083 "HTTP/1.1 204 No Content",
2084 "HTTP/1.1 205 Reset Content",
2085 "HTTP/1.1 304 Not Modified",
2086 "HTTP/1.1 302 Found",
2087 "HTTP/1.1 302 Found",
2088 "HTTP/1.1 301 Moved Permanently",
2089 "HTTP/1.1 301 Moved Permanently",
2090 "HTTP/1.1 200 Hunky-Dory",
2091 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502092 };
2093
mostynb91e0da982015-01-20 19:17:272094 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2095 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502096
2097 for (int i = 0; i < kNumUnreadBodies; ++i)
2098 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2099
[email protected]49639fa2011-12-20 23:22:412100 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162101 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202102 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012103 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162104 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182105 ASSERT_TRUE(response);
2106 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502107 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2108 std::string response_data;
bnc691fda62016-08-12 00:43:162109 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012110 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502111 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132112}
2113
mmenke5f94fda2016-06-02 20:54:132114// Sockets that receive extra data after a response is complete should not be
2115// reused.
bncd16676a2016-07-20 16:23:012116TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132117 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2118 MockWrite data_writes1[] = {
2119 MockWrite("HEAD / HTTP/1.1\r\n"
2120 "Host: www.borked.com\r\n"
2121 "Connection: keep-alive\r\n\r\n"),
2122 };
2123
2124 MockRead data_reads1[] = {
2125 MockRead("HTTP/1.1 200 OK\r\n"
2126 "Connection: keep-alive\r\n"
2127 "Content-Length: 22\r\n\r\n"
2128 "This server is borked."),
2129 };
2130
2131 MockWrite data_writes2[] = {
2132 MockWrite("GET /foo HTTP/1.1\r\n"
2133 "Host: www.borked.com\r\n"
2134 "Connection: keep-alive\r\n\r\n"),
2135 };
2136
2137 MockRead data_reads2[] = {
2138 MockRead("HTTP/1.1 200 OK\r\n"
2139 "Content-Length: 3\r\n\r\n"
2140 "foo"),
2141 };
2142 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2143 data_writes1, arraysize(data_writes1));
2144 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2145 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2146 data_writes2, arraysize(data_writes2));
2147 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2148
2149 TestCompletionCallback callback;
2150 HttpRequestInfo request1;
2151 request1.method = "HEAD";
2152 request1.url = GURL("http://www.borked.com/");
2153
bnc87dcefc2017-05-25 12:47:582154 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192155 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202156 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012157 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132158
2159 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2160 ASSERT_TRUE(response1);
2161 ASSERT_TRUE(response1->headers);
2162 EXPECT_EQ(200, response1->headers->response_code());
2163 EXPECT_TRUE(response1->headers->IsKeepAlive());
2164
2165 std::string response_data1;
robpercival214763f2016-07-01 23:27:012166 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132167 EXPECT_EQ("", response_data1);
2168 // Deleting the transaction attempts to release the socket back into the
2169 // socket pool.
2170 trans1.reset();
2171
2172 HttpRequestInfo request2;
2173 request2.method = "GET";
2174 request2.url = GURL("http://www.borked.com/foo");
2175
bnc87dcefc2017-05-25 12:47:582176 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192177 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202178 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012179 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132180
2181 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2182 ASSERT_TRUE(response2);
2183 ASSERT_TRUE(response2->headers);
2184 EXPECT_EQ(200, response2->headers->response_code());
2185
2186 std::string response_data2;
robpercival214763f2016-07-01 23:27:012187 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132188 EXPECT_EQ("foo", response_data2);
2189}
2190
bncd16676a2016-07-20 16:23:012191TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2193 MockWrite data_writes1[] = {
2194 MockWrite("GET / HTTP/1.1\r\n"
2195 "Host: www.borked.com\r\n"
2196 "Connection: keep-alive\r\n\r\n"),
2197 };
2198
2199 MockRead data_reads1[] = {
2200 MockRead("HTTP/1.1 200 OK\r\n"
2201 "Connection: keep-alive\r\n"
2202 "Content-Length: 22\r\n\r\n"
2203 "This server is borked."
2204 "Bonus data!"),
2205 };
2206
2207 MockWrite data_writes2[] = {
2208 MockWrite("GET /foo HTTP/1.1\r\n"
2209 "Host: www.borked.com\r\n"
2210 "Connection: keep-alive\r\n\r\n"),
2211 };
2212
2213 MockRead data_reads2[] = {
2214 MockRead("HTTP/1.1 200 OK\r\n"
2215 "Content-Length: 3\r\n\r\n"
2216 "foo"),
2217 };
2218 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2219 data_writes1, arraysize(data_writes1));
2220 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2221 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2222 data_writes2, arraysize(data_writes2));
2223 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2224
2225 TestCompletionCallback callback;
2226 HttpRequestInfo request1;
2227 request1.method = "GET";
2228 request1.url = GURL("http://www.borked.com/");
2229
bnc87dcefc2017-05-25 12:47:582230 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192231 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202232 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012233 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132234
2235 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2236 ASSERT_TRUE(response1);
2237 ASSERT_TRUE(response1->headers);
2238 EXPECT_EQ(200, response1->headers->response_code());
2239 EXPECT_TRUE(response1->headers->IsKeepAlive());
2240
2241 std::string response_data1;
robpercival214763f2016-07-01 23:27:012242 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132243 EXPECT_EQ("This server is borked.", response_data1);
2244 // Deleting the transaction attempts to release the socket back into the
2245 // socket pool.
2246 trans1.reset();
2247
2248 HttpRequestInfo request2;
2249 request2.method = "GET";
2250 request2.url = GURL("http://www.borked.com/foo");
2251
bnc87dcefc2017-05-25 12:47:582252 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192253 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202254 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012255 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132256
2257 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2258 ASSERT_TRUE(response2);
2259 ASSERT_TRUE(response2->headers);
2260 EXPECT_EQ(200, response2->headers->response_code());
2261
2262 std::string response_data2;
robpercival214763f2016-07-01 23:27:012263 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132264 EXPECT_EQ("foo", response_data2);
2265}
2266
bncd16676a2016-07-20 16:23:012267TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132268 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2269 MockWrite data_writes1[] = {
2270 MockWrite("GET / HTTP/1.1\r\n"
2271 "Host: www.borked.com\r\n"
2272 "Connection: keep-alive\r\n\r\n"),
2273 };
2274
2275 MockRead data_reads1[] = {
2276 MockRead("HTTP/1.1 200 OK\r\n"
2277 "Connection: keep-alive\r\n"
2278 "Transfer-Encoding: chunked\r\n\r\n"),
2279 MockRead("16\r\nThis server is borked.\r\n"),
2280 MockRead("0\r\n\r\nBonus data!"),
2281 };
2282
2283 MockWrite data_writes2[] = {
2284 MockWrite("GET /foo HTTP/1.1\r\n"
2285 "Host: www.borked.com\r\n"
2286 "Connection: keep-alive\r\n\r\n"),
2287 };
2288
2289 MockRead data_reads2[] = {
2290 MockRead("HTTP/1.1 200 OK\r\n"
2291 "Content-Length: 3\r\n\r\n"
2292 "foo"),
2293 };
2294 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2295 data_writes1, arraysize(data_writes1));
2296 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2297 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2298 data_writes2, arraysize(data_writes2));
2299 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2300
2301 TestCompletionCallback callback;
2302 HttpRequestInfo request1;
2303 request1.method = "GET";
2304 request1.url = GURL("http://www.borked.com/");
2305
bnc87dcefc2017-05-25 12:47:582306 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192307 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202308 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012309 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132310
2311 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2312 ASSERT_TRUE(response1);
2313 ASSERT_TRUE(response1->headers);
2314 EXPECT_EQ(200, response1->headers->response_code());
2315 EXPECT_TRUE(response1->headers->IsKeepAlive());
2316
2317 std::string response_data1;
robpercival214763f2016-07-01 23:27:012318 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132319 EXPECT_EQ("This server is borked.", response_data1);
2320 // Deleting the transaction attempts to release the socket back into the
2321 // socket pool.
2322 trans1.reset();
2323
2324 HttpRequestInfo request2;
2325 request2.method = "GET";
2326 request2.url = GURL("http://www.borked.com/foo");
2327
bnc87dcefc2017-05-25 12:47:582328 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192329 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202330 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012331 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132332
2333 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2334 ASSERT_TRUE(response2);
2335 ASSERT_TRUE(response2->headers);
2336 EXPECT_EQ(200, response2->headers->response_code());
2337
2338 std::string response_data2;
robpercival214763f2016-07-01 23:27:012339 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132340 EXPECT_EQ("foo", response_data2);
2341}
2342
2343// This is a little different from the others - it tests the case that the
2344// HttpStreamParser doesn't know if there's extra data on a socket or not when
2345// the HttpNetworkTransaction is torn down, because the response body hasn't
2346// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012347TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132348 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2349 MockWrite data_writes1[] = {
2350 MockWrite("GET / HTTP/1.1\r\n"
2351 "Host: www.borked.com\r\n"
2352 "Connection: keep-alive\r\n\r\n"),
2353 };
2354
2355 MockRead data_reads1[] = {
2356 MockRead("HTTP/1.1 200 OK\r\n"
2357 "Connection: keep-alive\r\n"
2358 "Transfer-Encoding: chunked\r\n\r\n"),
2359 MockRead("16\r\nThis server is borked.\r\n"),
2360 MockRead("0\r\n\r\nBonus data!"),
2361 };
2362 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2363 data_writes1, arraysize(data_writes1));
2364 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2365
2366 TestCompletionCallback callback;
2367 HttpRequestInfo request1;
2368 request1.method = "GET";
2369 request1.url = GURL("http://www.borked.com/");
2370
bnc87dcefc2017-05-25 12:47:582371 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192372 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582373 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012374 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132375
bnc87dcefc2017-05-25 12:47:582376 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132377 ASSERT_TRUE(response1);
2378 ASSERT_TRUE(response1->headers);
2379 EXPECT_EQ(200, response1->headers->response_code());
2380 EXPECT_TRUE(response1->headers->IsKeepAlive());
2381
2382 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2383 // response body.
bnc87dcefc2017-05-25 12:47:582384 trans.reset();
mmenke5f94fda2016-06-02 20:54:132385
2386 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2387 // socket can't be reused, rather than returning it to the socket pool.
2388 base::RunLoop().RunUntilIdle();
2389
2390 // There should be no idle sockets in the pool.
2391 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2392}
2393
[email protected]038e9a32008-10-08 22:40:162394// Test the request-challenge-retry sequence for basic auth.
2395// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012396TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422397 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162398 request.method = "GET";
bncce36dca22015-04-21 22:11:232399 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162400
vishal.b62985ca92015-04-17 08:45:512401 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072402 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092403 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162404 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272405
[email protected]f9ee6b52008-11-08 06:46:232406 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232407 MockWrite(
2408 "GET / HTTP/1.1\r\n"
2409 "Host: www.example.org\r\n"
2410 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232411 };
2412
[email protected]038e9a32008-10-08 22:40:162413 MockRead data_reads1[] = {
2414 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2415 // Give a couple authenticate options (only the middle one is actually
2416 // supported).
[email protected]22927ad2009-09-21 19:56:192417 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162418 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2419 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2420 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2421 // Large content-length -- won't matter, as connection will be reset.
2422 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062423 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162424 };
2425
2426 // After calling trans->RestartWithAuth(), this is the request we should
2427 // be issuing -- the final header line contains the credentials.
2428 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232429 MockWrite(
2430 "GET / HTTP/1.1\r\n"
2431 "Host: www.example.org\r\n"
2432 "Connection: keep-alive\r\n"
2433 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162434 };
2435
2436 // Lastly, the server responds with the actual content.
2437 MockRead data_reads2[] = {
2438 MockRead("HTTP/1.0 200 OK\r\n"),
2439 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2440 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062441 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162442 };
2443
[email protected]31a2bfe2010-02-09 08:03:392444 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2445 data_writes1, arraysize(data_writes1));
2446 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2447 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072448 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2449 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162450
[email protected]49639fa2011-12-20 23:22:412451 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162452
tfarina42834112016-09-22 13:38:202453 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012454 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162455
2456 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012457 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162458
[email protected]58e32bb2013-01-21 18:23:252459 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162460 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252461 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2462
sclittlefb249892015-09-10 21:33:222463 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162464 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222465 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162466 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192467
bnc691fda62016-08-12 00:43:162468 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522469 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042470 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162471
[email protected]49639fa2011-12-20 23:22:412472 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162473
bnc691fda62016-08-12 00:43:162474 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162476
2477 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012478 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162479
[email protected]58e32bb2013-01-21 18:23:252480 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162481 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252482 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2483 // The load timing after restart should have a new socket ID, and times after
2484 // those of the first load timing.
2485 EXPECT_LE(load_timing_info1.receive_headers_end,
2486 load_timing_info2.connect_timing.connect_start);
2487 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2488
sclittlefb249892015-09-10 21:33:222489 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162490 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222491 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162492 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192493
bnc691fda62016-08-12 00:43:162494 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522495 ASSERT_TRUE(response);
2496 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162497 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162498}
2499
ttuttled9dbc652015-09-29 20:00:592500// Test the request-challenge-retry sequence for basic auth.
2501// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012502TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592503 HttpRequestInfo request;
2504 request.method = "GET";
2505 request.url = GURL("http://www.example.org/");
ttuttled9dbc652015-09-29 20:00:592506
2507 TestNetLog log;
2508 MockHostResolver* resolver = new MockHostResolver();
2509 session_deps_.net_log = &log;
2510 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092511 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162512 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592513
2514 resolver->rules()->ClearRules();
2515 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2516
2517 MockWrite data_writes1[] = {
2518 MockWrite("GET / HTTP/1.1\r\n"
2519 "Host: www.example.org\r\n"
2520 "Connection: keep-alive\r\n\r\n"),
2521 };
2522
2523 MockRead data_reads1[] = {
2524 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2525 // Give a couple authenticate options (only the middle one is actually
2526 // supported).
2527 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2528 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2529 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2530 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2531 // Large content-length -- won't matter, as connection will be reset.
2532 MockRead("Content-Length: 10000\r\n\r\n"),
2533 MockRead(SYNCHRONOUS, ERR_FAILED),
2534 };
2535
2536 // After calling trans->RestartWithAuth(), this is the request we should
2537 // be issuing -- the final header line contains the credentials.
2538 MockWrite data_writes2[] = {
2539 MockWrite("GET / HTTP/1.1\r\n"
2540 "Host: www.example.org\r\n"
2541 "Connection: keep-alive\r\n"
2542 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2543 };
2544
2545 // Lastly, the server responds with the actual content.
2546 MockRead data_reads2[] = {
2547 MockRead("HTTP/1.0 200 OK\r\n"),
2548 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2549 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2550 };
2551
2552 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2553 data_writes1, arraysize(data_writes1));
2554 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2555 data_writes2, arraysize(data_writes2));
2556 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2557 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2558
2559 TestCompletionCallback callback1;
2560
bnc691fda62016-08-12 00:43:162561 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202562 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592563
2564 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162565 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592566 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2567
2568 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
bnc691fda62016-08-12 00:43:162569 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592570 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
bnc691fda62016-08-12 00:43:162571 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592572
bnc691fda62016-08-12 00:43:162573 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592574 ASSERT_TRUE(response);
2575 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2576
2577 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162578 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592579 ASSERT_FALSE(endpoint.address().empty());
2580 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2581
2582 resolver->rules()->ClearRules();
2583 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2584
2585 TestCompletionCallback callback2;
2586
bnc691fda62016-08-12 00:43:162587 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592588 AuthCredentials(kFoo, kBar), callback2.callback())));
2589
2590 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162591 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592592 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2593 // The load timing after restart should have a new socket ID, and times after
2594 // those of the first load timing.
2595 EXPECT_LE(load_timing_info1.receive_headers_end,
2596 load_timing_info2.connect_timing.connect_start);
2597 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2598
2599 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
bnc691fda62016-08-12 00:43:162600 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
ttuttled9dbc652015-09-29 20:00:592601 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
bnc691fda62016-08-12 00:43:162602 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592603
bnc691fda62016-08-12 00:43:162604 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592605 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522606 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592607 EXPECT_EQ(100, response->headers->GetContentLength());
2608
bnc691fda62016-08-12 00:43:162609 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592610 ASSERT_FALSE(endpoint.address().empty());
2611 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2612}
2613
bncd16676a2016-07-20 16:23:012614TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462615 HttpRequestInfo request;
2616 request.method = "GET";
bncce36dca22015-04-21 22:11:232617 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292618 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462619
danakj1fd259a02016-04-16 03:17:092620 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162621 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272622
[email protected]861fcd52009-08-26 02:33:462623 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232624 MockWrite(
2625 "GET / HTTP/1.1\r\n"
2626 "Host: www.example.org\r\n"
2627 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462628 };
2629
2630 MockRead data_reads[] = {
2631 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2632 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2633 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2634 // Large content-length -- won't matter, as connection will be reset.
2635 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062636 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462637 };
2638
[email protected]31a2bfe2010-02-09 08:03:392639 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2640 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072641 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412642 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462643
tfarina42834112016-09-22 13:38:202644 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012645 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462646
2647 rv = callback.WaitForResult();
2648 EXPECT_EQ(0, rv);
2649
sclittlefb249892015-09-10 21:33:222650 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162651 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:222652 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162653 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192654
bnc691fda62016-08-12 00:43:162655 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522656 ASSERT_TRUE(response);
2657 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462658}
2659
[email protected]2d2697f92009-02-18 21:00:322660// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2661// connection.
bncd16676a2016-07-20 16:23:012662TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182663 // On the second pass, the body read of the auth challenge is synchronous, so
2664 // IsConnectedAndIdle returns false. The socket should still be drained and
2665 // reused. See http://crbug.com/544255.
2666 for (int i = 0; i < 2; ++i) {
2667 HttpRequestInfo request;
2668 request.method = "GET";
2669 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322670
mmenkecc2298e2015-12-07 18:20:182671 TestNetLog log;
2672 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272674
mmenkecc2298e2015-12-07 18:20:182675 MockWrite data_writes[] = {
2676 MockWrite(ASYNC, 0,
2677 "GET / HTTP/1.1\r\n"
2678 "Host: www.example.org\r\n"
2679 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322680
bnc691fda62016-08-12 00:43:162681 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182682 // be issuing -- the final header line contains the credentials.
2683 MockWrite(ASYNC, 6,
2684 "GET / HTTP/1.1\r\n"
2685 "Host: www.example.org\r\n"
2686 "Connection: keep-alive\r\n"
2687 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2688 };
[email protected]2d2697f92009-02-18 21:00:322689
mmenkecc2298e2015-12-07 18:20:182690 MockRead data_reads[] = {
2691 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2692 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2693 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2694 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2695 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322696
mmenkecc2298e2015-12-07 18:20:182697 // Lastly, the server responds with the actual content.
2698 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2699 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2700 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2701 MockRead(ASYNC, 10, "Hello"),
2702 };
[email protected]2d2697f92009-02-18 21:00:322703
mmenkecc2298e2015-12-07 18:20:182704 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2705 arraysize(data_writes));
2706 data.set_busy_before_sync_reads(true);
2707 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462708
mmenkecc2298e2015-12-07 18:20:182709 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322710
bnc691fda62016-08-12 00:43:162711 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202712 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012713 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322714
mmenkecc2298e2015-12-07 18:20:182715 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162716 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182717 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322718
bnc691fda62016-08-12 00:43:162719 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182720 ASSERT_TRUE(response);
2721 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322722
mmenkecc2298e2015-12-07 18:20:182723 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252724
bnc691fda62016-08-12 00:43:162725 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2726 callback2.callback());
robpercival214763f2016-07-01 23:27:012727 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322728
mmenkecc2298e2015-12-07 18:20:182729 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162730 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182731 TestLoadTimingReused(load_timing_info2);
2732 // The load timing after restart should have the same socket ID, and times
2733 // those of the first load timing.
2734 EXPECT_LE(load_timing_info1.receive_headers_end,
2735 load_timing_info2.send_start);
2736 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322737
bnc691fda62016-08-12 00:43:162738 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182739 ASSERT_TRUE(response);
2740 EXPECT_FALSE(response->auth_challenge);
2741 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322742
mmenkecc2298e2015-12-07 18:20:182743 std::string response_data;
bnc691fda62016-08-12 00:43:162744 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322745
mmenkecc2298e2015-12-07 18:20:182746 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
bnc691fda62016-08-12 00:43:162747 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
mmenkecc2298e2015-12-07 18:20:182748 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
bnc691fda62016-08-12 00:43:162749 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182750 }
[email protected]2d2697f92009-02-18 21:00:322751}
2752
2753// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2754// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012755TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422756 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322757 request.method = "GET";
bncce36dca22015-04-21 22:11:232758 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322759
danakj1fd259a02016-04-16 03:17:092760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272761
[email protected]2d2697f92009-02-18 21:00:322762 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162763 MockWrite("GET / HTTP/1.1\r\n"
2764 "Host: www.example.org\r\n"
2765 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322766
bnc691fda62016-08-12 00:43:162767 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232768 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162769 MockWrite("GET / HTTP/1.1\r\n"
2770 "Host: www.example.org\r\n"
2771 "Connection: keep-alive\r\n"
2772 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322773 };
2774
[email protected]2d2697f92009-02-18 21:00:322775 MockRead data_reads1[] = {
2776 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2777 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312778 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322779
2780 // Lastly, the server responds with the actual content.
2781 MockRead("HTTP/1.1 200 OK\r\n"),
2782 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502783 MockRead("Content-Length: 5\r\n\r\n"),
2784 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322785 };
2786
[email protected]2d0a4f92011-05-05 16:38:462787 // An incorrect reconnect would cause this to be read.
2788 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062789 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462790 };
2791
[email protected]31a2bfe2010-02-09 08:03:392792 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2793 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462794 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2795 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072796 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2797 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322798
[email protected]49639fa2011-12-20 23:22:412799 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322800
bnc691fda62016-08-12 00:43:162801 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202802 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012803 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322804
2805 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012806 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322807
bnc691fda62016-08-12 00:43:162808 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522809 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042810 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322811
[email protected]49639fa2011-12-20 23:22:412812 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322813
bnc691fda62016-08-12 00:43:162814 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322816
2817 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012818 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322819
bnc691fda62016-08-12 00:43:162820 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522821 ASSERT_TRUE(response);
2822 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502823 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322824}
2825
2826// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2827// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012828TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422829 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322830 request.method = "GET";
bncce36dca22015-04-21 22:11:232831 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322832
danakj1fd259a02016-04-16 03:17:092833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272834
[email protected]2d2697f92009-02-18 21:00:322835 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162836 MockWrite("GET / HTTP/1.1\r\n"
2837 "Host: www.example.org\r\n"
2838 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322839
bnc691fda62016-08-12 00:43:162840 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232841 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162842 MockWrite("GET / HTTP/1.1\r\n"
2843 "Host: www.example.org\r\n"
2844 "Connection: keep-alive\r\n"
2845 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322846 };
2847
2848 // Respond with 5 kb of response body.
2849 std::string large_body_string("Unauthorized");
2850 large_body_string.append(5 * 1024, ' ');
2851 large_body_string.append("\r\n");
2852
2853 MockRead data_reads1[] = {
2854 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2855 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2856 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2857 // 5134 = 12 + 5 * 1024 + 2
2858 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062859 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322860
2861 // Lastly, the server responds with the actual content.
2862 MockRead("HTTP/1.1 200 OK\r\n"),
2863 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502864 MockRead("Content-Length: 5\r\n\r\n"),
2865 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322866 };
2867
[email protected]2d0a4f92011-05-05 16:38:462868 // An incorrect reconnect would cause this to be read.
2869 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062870 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462871 };
2872
[email protected]31a2bfe2010-02-09 08:03:392873 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2874 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462875 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2876 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072877 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2878 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322879
[email protected]49639fa2011-12-20 23:22:412880 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322881
bnc691fda62016-08-12 00:43:162882 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202883 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322885
2886 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012887 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322888
bnc691fda62016-08-12 00:43:162889 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522890 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042891 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322892
[email protected]49639fa2011-12-20 23:22:412893 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322894
bnc691fda62016-08-12 00:43:162895 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012896 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322897
2898 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012899 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322900
bnc691fda62016-08-12 00:43:162901 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522902 ASSERT_TRUE(response);
2903 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502904 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322905}
2906
2907// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312908// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012909TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312910 HttpRequestInfo request;
2911 request.method = "GET";
bncce36dca22015-04-21 22:11:232912 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312913
danakj1fd259a02016-04-16 03:17:092914 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272915
[email protected]11203f012009-11-12 23:02:312916 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232917 MockWrite(
2918 "GET / HTTP/1.1\r\n"
2919 "Host: www.example.org\r\n"
2920 "Connection: keep-alive\r\n\r\n"),
2921 // This simulates the seemingly successful write to a closed connection
2922 // if the bug is not fixed.
2923 MockWrite(
2924 "GET / HTTP/1.1\r\n"
2925 "Host: www.example.org\r\n"
2926 "Connection: keep-alive\r\n"
2927 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312928 };
2929
2930 MockRead data_reads1[] = {
2931 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2932 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2933 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2934 MockRead("Content-Length: 14\r\n\r\n"),
2935 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062936 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312937 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062938 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312939 };
2940
bnc691fda62016-08-12 00:43:162941 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312942 // be issuing -- the final header line contains the credentials.
2943 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232944 MockWrite(
2945 "GET / HTTP/1.1\r\n"
2946 "Host: www.example.org\r\n"
2947 "Connection: keep-alive\r\n"
2948 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312949 };
2950
2951 // Lastly, the server responds with the actual content.
2952 MockRead data_reads2[] = {
2953 MockRead("HTTP/1.1 200 OK\r\n"),
2954 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502955 MockRead("Content-Length: 5\r\n\r\n"),
2956 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312957 };
2958
[email protected]31a2bfe2010-02-09 08:03:392959 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2960 data_writes1, arraysize(data_writes1));
2961 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2962 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072963 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2964 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312965
[email protected]49639fa2011-12-20 23:22:412966 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312967
bnc691fda62016-08-12 00:43:162968 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202969 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012970 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312971
2972 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012973 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312974
bnc691fda62016-08-12 00:43:162975 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522976 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042977 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312978
[email protected]49639fa2011-12-20 23:22:412979 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312980
bnc691fda62016-08-12 00:43:162981 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012982 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:312983
2984 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012985 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:312986
bnc691fda62016-08-12 00:43:162987 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522988 ASSERT_TRUE(response);
2989 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502990 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312991}
2992
[email protected]394816e92010-08-03 07:38:592993// Test the request-challenge-retry sequence for basic auth, over a connection
2994// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:012995TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:012996 HttpRequestInfo request;
2997 request.method = "GET";
bncce36dca22015-04-21 22:11:232998 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012999 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293000 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013001
3002 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033003 session_deps_.proxy_service =
3004 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513005 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013006 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093007 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013008
3009 // Since we have proxy, should try to establish tunnel.
3010 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543011 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173012 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543013 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013014 };
3015
mmenkee71e15332015-10-07 16:39:543016 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013017 // connection.
3018 MockRead data_reads1[] = {
3019 // No credentials.
3020 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3021 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543022 };
ttuttle34f63b52015-03-05 04:33:013023
mmenkee71e15332015-10-07 16:39:543024 // Since the first connection couldn't be reused, need to establish another
3025 // once given credentials.
3026 MockWrite data_writes2[] = {
3027 // After calling trans->RestartWithAuth(), this is the request we should
3028 // be issuing -- the final header line contains the credentials.
3029 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173030 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543031 "Proxy-Connection: keep-alive\r\n"
3032 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3033
3034 MockWrite("GET / HTTP/1.1\r\n"
3035 "Host: www.example.org\r\n"
3036 "Connection: keep-alive\r\n\r\n"),
3037 };
3038
3039 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013040 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3041
3042 MockRead("HTTP/1.1 200 OK\r\n"),
3043 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3044 MockRead("Content-Length: 5\r\n\r\n"),
3045 MockRead(SYNCHRONOUS, "hello"),
3046 };
3047
3048 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3049 data_writes1, arraysize(data_writes1));
3050 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543051 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3052 data_writes2, arraysize(data_writes2));
3053 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013054 SSLSocketDataProvider ssl(ASYNC, OK);
3055 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3056
3057 TestCompletionCallback callback1;
3058
bnc87dcefc2017-05-25 12:47:583059 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193060 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013061
3062 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013063 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013064
3065 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013066 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463067 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013068 log.GetEntries(&entries);
3069 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003070 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3071 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013072 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003073 entries, pos,
3074 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3075 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013076
3077 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523078 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013079 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523080 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013081 EXPECT_EQ(407, response->headers->response_code());
3082 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3083 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3084
3085 LoadTimingInfo load_timing_info;
3086 // CONNECT requests and responses are handled at the connect job level, so
3087 // the transaction does not yet have a connection.
3088 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3089
3090 TestCompletionCallback callback2;
3091
3092 rv =
3093 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013094 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013095
3096 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013097 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013098
3099 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523100 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013101
3102 EXPECT_TRUE(response->headers->IsKeepAlive());
3103 EXPECT_EQ(200, response->headers->response_code());
3104 EXPECT_EQ(5, response->headers->GetContentLength());
3105 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3106
3107 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523108 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013109
3110 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3111 TestLoadTimingNotReusedWithPac(load_timing_info,
3112 CONNECT_TIMING_HAS_SSL_TIMES);
3113
3114 trans.reset();
3115 session->CloseAllConnections();
3116}
3117
3118// Test the request-challenge-retry sequence for basic auth, over a connection
3119// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013120TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593121 HttpRequestInfo request;
3122 request.method = "GET";
bncce36dca22015-04-21 22:11:233123 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593124 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293125 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593126
[email protected]cb9bf6ca2011-01-28 13:15:273127 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033128 session_deps_.proxy_service =
3129 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513130 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073131 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093132 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273133
[email protected]394816e92010-08-03 07:38:593134 // Since we have proxy, should try to establish tunnel.
3135 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543136 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173137 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543138 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113139 };
3140
mmenkee71e15332015-10-07 16:39:543141 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083142 // connection.
3143 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543144 // No credentials.
3145 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3146 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3147 MockRead("Proxy-Connection: close\r\n\r\n"),
3148 };
mmenkee0b5c882015-08-26 20:29:113149
mmenkee71e15332015-10-07 16:39:543150 MockWrite data_writes2[] = {
3151 // After calling trans->RestartWithAuth(), this is the request we should
3152 // be issuing -- the final header line contains the credentials.
3153 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173154 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543155 "Proxy-Connection: keep-alive\r\n"
3156 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083157
mmenkee71e15332015-10-07 16:39:543158 MockWrite("GET / HTTP/1.1\r\n"
3159 "Host: www.example.org\r\n"
3160 "Connection: keep-alive\r\n\r\n"),
3161 };
3162
3163 MockRead data_reads2[] = {
3164 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3165
3166 MockRead("HTTP/1.1 200 OK\r\n"),
3167 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3168 MockRead("Content-Length: 5\r\n\r\n"),
3169 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593170 };
3171
3172 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3173 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073174 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543175 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3176 data_writes2, arraysize(data_writes2));
3177 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063178 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073179 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593180
[email protected]49639fa2011-12-20 23:22:413181 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593182
bnc87dcefc2017-05-25 12:47:583183 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193184 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503185
[email protected]49639fa2011-12-20 23:22:413186 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593188
3189 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013190 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463191 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403192 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593193 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003194 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3195 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593196 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403197 entries, pos,
mikecirone8b85c432016-09-08 19:11:003198 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3199 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593200
3201 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523202 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013203 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523204 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593205 EXPECT_EQ(407, response->headers->response_code());
3206 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043207 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593208
[email protected]029c83b62013-01-24 05:28:203209 LoadTimingInfo load_timing_info;
3210 // CONNECT requests and responses are handled at the connect job level, so
3211 // the transaction does not yet have a connection.
3212 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3213
[email protected]49639fa2011-12-20 23:22:413214 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593215
[email protected]49639fa2011-12-20 23:22:413216 rv = trans->RestartWithAuth(
3217 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013218 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593219
3220 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013221 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593222
3223 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523224 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593225
3226 EXPECT_TRUE(response->headers->IsKeepAlive());
3227 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503228 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593229 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3230
3231 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523232 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503233
[email protected]029c83b62013-01-24 05:28:203234 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3235 TestLoadTimingNotReusedWithPac(load_timing_info,
3236 CONNECT_TIMING_HAS_SSL_TIMES);
3237
[email protected]0b0bf032010-09-21 18:08:503238 trans.reset();
[email protected]102e27c2011-02-23 01:01:313239 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593240}
3241
[email protected]11203f012009-11-12 23:02:313242// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013243// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013244TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233245 // On the second pass, the body read of the auth challenge is synchronous, so
3246 // IsConnectedAndIdle returns false. The socket should still be drained and
3247 // reused. See http://crbug.com/544255.
3248 for (int i = 0; i < 2; ++i) {
3249 HttpRequestInfo request;
3250 request.method = "GET";
3251 request.url = GURL("https://www.example.org/");
3252 // Ensure that proxy authentication is attempted even
3253 // when the no authentication data flag is set.
3254 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013255
mmenked39192ee2015-12-09 00:57:233256 // Configure against proxy server "myproxy:70".
3257 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3258 BoundTestNetLog log;
3259 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093260 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013261
bnc691fda62016-08-12 00:43:163262 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013263
mmenked39192ee2015-12-09 00:57:233264 // Since we have proxy, should try to establish tunnel.
3265 MockWrite data_writes1[] = {
3266 MockWrite(ASYNC, 0,
3267 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3268 "Host: www.example.org:443\r\n"
3269 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013270
bnc691fda62016-08-12 00:43:163271 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233272 // be issuing -- the final header line contains the credentials.
3273 MockWrite(ASYNC, 3,
3274 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3275 "Host: www.example.org:443\r\n"
3276 "Proxy-Connection: keep-alive\r\n"
3277 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3278 };
ttuttle34f63b52015-03-05 04:33:013279
mmenked39192ee2015-12-09 00:57:233280 // The proxy responds to the connect with a 407, using a persistent
3281 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3282 MockRead data_reads1[] = {
3283 // No credentials.
3284 MockRead(ASYNC, 1,
3285 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3286 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3287 "Proxy-Connection: keep-alive\r\n"
3288 "Content-Length: 10\r\n\r\n"),
3289 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013290
mmenked39192ee2015-12-09 00:57:233291 // Wrong credentials (wrong password).
3292 MockRead(ASYNC, 4,
3293 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3294 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3295 "Proxy-Connection: keep-alive\r\n"
3296 "Content-Length: 10\r\n\r\n"),
3297 // No response body because the test stops reading here.
3298 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3299 };
ttuttle34f63b52015-03-05 04:33:013300
mmenked39192ee2015-12-09 00:57:233301 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3302 arraysize(data_writes1));
3303 data1.set_busy_before_sync_reads(true);
3304 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013305
mmenked39192ee2015-12-09 00:57:233306 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013307
bnc691fda62016-08-12 00:43:163308 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013309 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013310
mmenked39192ee2015-12-09 00:57:233311 TestNetLogEntry::List entries;
3312 log.GetEntries(&entries);
3313 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003314 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3315 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233316 ExpectLogContainsSomewhere(
3317 entries, pos,
mikecirone8b85c432016-09-08 19:11:003318 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3319 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013320
bnc691fda62016-08-12 00:43:163321 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233322 ASSERT_TRUE(response);
3323 ASSERT_TRUE(response->headers);
3324 EXPECT_TRUE(response->headers->IsKeepAlive());
3325 EXPECT_EQ(407, response->headers->response_code());
3326 EXPECT_EQ(10, response->headers->GetContentLength());
3327 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3328 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013329
mmenked39192ee2015-12-09 00:57:233330 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013331
mmenked39192ee2015-12-09 00:57:233332 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163333 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3334 callback2.callback());
robpercival214763f2016-07-01 23:27:013335 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013336
bnc691fda62016-08-12 00:43:163337 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233338 ASSERT_TRUE(response);
3339 ASSERT_TRUE(response->headers);
3340 EXPECT_TRUE(response->headers->IsKeepAlive());
3341 EXPECT_EQ(407, response->headers->response_code());
3342 EXPECT_EQ(10, response->headers->GetContentLength());
3343 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3344 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013345
mmenked39192ee2015-12-09 00:57:233346 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3347 // out of scope.
3348 session->CloseAllConnections();
3349 }
ttuttle34f63b52015-03-05 04:33:013350}
3351
3352// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3353// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013354TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233355 // On the second pass, the body read of the auth challenge is synchronous, so
3356 // IsConnectedAndIdle returns false. The socket should still be drained and
3357 // reused. See http://crbug.com/544255.
3358 for (int i = 0; i < 2; ++i) {
3359 HttpRequestInfo request;
3360 request.method = "GET";
3361 request.url = GURL("https://www.example.org/");
3362 // Ensure that proxy authentication is attempted even
3363 // when the no authentication data flag is set.
3364 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3365
3366 // Configure against proxy server "myproxy:70".
3367 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3368 BoundTestNetLog log;
3369 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093370 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233371
bnc691fda62016-08-12 00:43:163372 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233373
3374 // Since we have proxy, should try to establish tunnel.
3375 MockWrite data_writes1[] = {
3376 MockWrite(ASYNC, 0,
3377 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3378 "Host: www.example.org:443\r\n"
3379 "Proxy-Connection: keep-alive\r\n\r\n"),
3380
bnc691fda62016-08-12 00:43:163381 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233382 // be issuing -- the final header line contains the credentials.
3383 MockWrite(ASYNC, 3,
3384 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3385 "Host: www.example.org:443\r\n"
3386 "Proxy-Connection: keep-alive\r\n"
3387 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3388 };
3389
3390 // The proxy responds to the connect with a 407, using a persistent
3391 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3392 MockRead data_reads1[] = {
3393 // No credentials.
3394 MockRead(ASYNC, 1,
3395 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3396 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3397 "Content-Length: 10\r\n\r\n"),
3398 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3399
3400 // Wrong credentials (wrong password).
3401 MockRead(ASYNC, 4,
3402 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3403 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3404 "Content-Length: 10\r\n\r\n"),
3405 // No response body because the test stops reading here.
3406 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3407 };
3408
3409 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3410 arraysize(data_writes1));
3411 data1.set_busy_before_sync_reads(true);
3412 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3413
3414 TestCompletionCallback callback1;
3415
bnc691fda62016-08-12 00:43:163416 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013417 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233418
3419 TestNetLogEntry::List entries;
3420 log.GetEntries(&entries);
3421 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003422 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3423 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233424 ExpectLogContainsSomewhere(
3425 entries, pos,
mikecirone8b85c432016-09-08 19:11:003426 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3427 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233428
bnc691fda62016-08-12 00:43:163429 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233430 ASSERT_TRUE(response);
3431 ASSERT_TRUE(response->headers);
3432 EXPECT_TRUE(response->headers->IsKeepAlive());
3433 EXPECT_EQ(407, response->headers->response_code());
3434 EXPECT_EQ(10, response->headers->GetContentLength());
3435 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3436 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3437
3438 TestCompletionCallback callback2;
3439
3440 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163441 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3442 callback2.callback());
robpercival214763f2016-07-01 23:27:013443 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233444
bnc691fda62016-08-12 00:43:163445 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233446 ASSERT_TRUE(response);
3447 ASSERT_TRUE(response->headers);
3448 EXPECT_TRUE(response->headers->IsKeepAlive());
3449 EXPECT_EQ(407, response->headers->response_code());
3450 EXPECT_EQ(10, response->headers->GetContentLength());
3451 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3452 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3453
3454 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3455 // out of scope.
3456 session->CloseAllConnections();
3457 }
3458}
3459
3460// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3461// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3462// the case the server sends extra data on the original socket, so it can't be
3463// reused.
bncd16676a2016-07-20 16:23:013464TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273465 HttpRequestInfo request;
3466 request.method = "GET";
bncce36dca22015-04-21 22:11:233467 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273468 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293469 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273470
[email protected]2d2697f92009-02-18 21:00:323471 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233472 session_deps_.proxy_service =
3473 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513474 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073475 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093476 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323477
[email protected]2d2697f92009-02-18 21:00:323478 // Since we have proxy, should try to establish tunnel.
3479 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233480 MockWrite(ASYNC, 0,
3481 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173482 "Host: www.example.org:443\r\n"
3483 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233484 };
[email protected]2d2697f92009-02-18 21:00:323485
mmenked39192ee2015-12-09 00:57:233486 // The proxy responds to the connect with a 407, using a persistent, but sends
3487 // extra data, so the socket cannot be reused.
3488 MockRead data_reads1[] = {
3489 // No credentials.
3490 MockRead(ASYNC, 1,
3491 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3492 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3493 "Content-Length: 10\r\n\r\n"),
3494 MockRead(SYNCHRONOUS, 2, "0123456789"),
3495 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3496 };
3497
3498 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233499 // After calling trans->RestartWithAuth(), this is the request we should
3500 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233501 MockWrite(ASYNC, 0,
3502 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173503 "Host: www.example.org:443\r\n"
3504 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233505 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3506
3507 MockWrite(ASYNC, 2,
3508 "GET / HTTP/1.1\r\n"
3509 "Host: www.example.org\r\n"
3510 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323511 };
3512
mmenked39192ee2015-12-09 00:57:233513 MockRead data_reads2[] = {
3514 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323515
mmenked39192ee2015-12-09 00:57:233516 MockRead(ASYNC, 3,
3517 "HTTP/1.1 200 OK\r\n"
3518 "Content-Type: text/html; charset=iso-8859-1\r\n"
3519 "Content-Length: 5\r\n\r\n"),
3520 // No response body because the test stops reading here.
3521 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323522 };
3523
mmenked39192ee2015-12-09 00:57:233524 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3525 arraysize(data_writes1));
3526 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073527 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233528 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3529 arraysize(data_writes2));
3530 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3531 SSLSocketDataProvider ssl(ASYNC, OK);
3532 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323533
[email protected]49639fa2011-12-20 23:22:413534 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323535
bnc87dcefc2017-05-25 12:47:583536 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193537 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323538
mmenked39192ee2015-12-09 00:57:233539 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013540 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233541
mmenke43758e62015-05-04 21:09:463542 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403543 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393544 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003545 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3546 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393547 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403548 entries, pos,
mikecirone8b85c432016-09-08 19:11:003549 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3550 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323551
[email protected]1c773ea12009-04-28 19:58:423552 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243553 ASSERT_TRUE(response);
3554 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323555 EXPECT_TRUE(response->headers->IsKeepAlive());
3556 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423557 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043558 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323559
mmenked39192ee2015-12-09 00:57:233560 LoadTimingInfo load_timing_info;
3561 // CONNECT requests and responses are handled at the connect job level, so
3562 // the transaction does not yet have a connection.
3563 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3564
[email protected]49639fa2011-12-20 23:22:413565 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323566
mmenked39192ee2015-12-09 00:57:233567 rv =
3568 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013569 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323570
[email protected]2d2697f92009-02-18 21:00:323571 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233572 EXPECT_EQ(200, response->headers->response_code());
3573 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423574 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133575
mmenked39192ee2015-12-09 00:57:233576 // The password prompt info should not be set.
3577 EXPECT_FALSE(response->auth_challenge);
3578
3579 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3580 TestLoadTimingNotReusedWithPac(load_timing_info,
3581 CONNECT_TIMING_HAS_SSL_TIMES);
3582
3583 trans.reset();
[email protected]102e27c2011-02-23 01:01:313584 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323585}
3586
mmenkee71e15332015-10-07 16:39:543587// Test the case a proxy closes a socket while the challenge body is being
3588// drained.
bncd16676a2016-07-20 16:23:013589TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543590 HttpRequestInfo request;
3591 request.method = "GET";
3592 request.url = GURL("https://www.example.org/");
3593 // Ensure that proxy authentication is attempted even
3594 // when the no authentication data flag is set.
3595 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3596
3597 // Configure against proxy server "myproxy:70".
3598 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093599 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543600
bnc691fda62016-08-12 00:43:163601 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543602
3603 // Since we have proxy, should try to establish tunnel.
3604 MockWrite data_writes1[] = {
3605 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173606 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543607 "Proxy-Connection: keep-alive\r\n\r\n"),
3608 };
3609
3610 // The proxy responds to the connect with a 407, using a persistent
3611 // connection.
3612 MockRead data_reads1[] = {
3613 // No credentials.
3614 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3615 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3616 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3617 // Server hands up in the middle of the body.
3618 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3619 };
3620
3621 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163622 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543623 // be issuing -- the final header line contains the credentials.
3624 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173625 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543626 "Proxy-Connection: keep-alive\r\n"
3627 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3628
3629 MockWrite("GET / HTTP/1.1\r\n"
3630 "Host: www.example.org\r\n"
3631 "Connection: keep-alive\r\n\r\n"),
3632 };
3633
3634 MockRead data_reads2[] = {
3635 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3636
3637 MockRead("HTTP/1.1 200 OK\r\n"),
3638 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3639 MockRead("Content-Length: 5\r\n\r\n"),
3640 MockRead(SYNCHRONOUS, "hello"),
3641 };
3642
3643 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3644 data_writes1, arraysize(data_writes1));
3645 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3646 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3647 data_writes2, arraysize(data_writes2));
3648 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3649 SSLSocketDataProvider ssl(ASYNC, OK);
3650 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3651
3652 TestCompletionCallback callback;
3653
tfarina42834112016-09-22 13:38:203654 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013655 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543656
bnc691fda62016-08-12 00:43:163657 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543658 ASSERT_TRUE(response);
3659 ASSERT_TRUE(response->headers);
3660 EXPECT_TRUE(response->headers->IsKeepAlive());
3661 EXPECT_EQ(407, response->headers->response_code());
3662 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3663
bnc691fda62016-08-12 00:43:163664 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013665 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543666
bnc691fda62016-08-12 00:43:163667 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543668 ASSERT_TRUE(response);
3669 ASSERT_TRUE(response->headers);
3670 EXPECT_TRUE(response->headers->IsKeepAlive());
3671 EXPECT_EQ(200, response->headers->response_code());
3672 std::string body;
bnc691fda62016-08-12 00:43:163673 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543674 EXPECT_EQ("hello", body);
3675}
3676
[email protected]a8e9b162009-03-12 00:06:443677// Test that we don't read the response body when we fail to establish a tunnel,
3678// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013679TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273680 HttpRequestInfo request;
3681 request.method = "GET";
bncce36dca22015-04-21 22:11:233682 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273683
[email protected]a8e9b162009-03-12 00:06:443684 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033685 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443686
danakj1fd259a02016-04-16 03:17:093687 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443688
bnc691fda62016-08-12 00:43:163689 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443690
[email protected]a8e9b162009-03-12 00:06:443691 // Since we have proxy, should try to establish tunnel.
3692 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173693 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3694 "Host: www.example.org:443\r\n"
3695 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443696 };
3697
3698 // The proxy responds to the connect with a 407.
3699 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243700 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3701 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3702 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233703 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243704 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443705 };
3706
[email protected]31a2bfe2010-02-09 08:03:393707 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3708 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073709 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443710
[email protected]49639fa2011-12-20 23:22:413711 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443712
tfarina42834112016-09-22 13:38:203713 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013714 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443715
3716 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013717 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443718
bnc691fda62016-08-12 00:43:163719 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243720 ASSERT_TRUE(response);
3721 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443722 EXPECT_TRUE(response->headers->IsKeepAlive());
3723 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423724 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443725
3726 std::string response_data;
bnc691fda62016-08-12 00:43:163727 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013728 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183729
3730 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313731 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443732}
3733
ttuttle7933c112015-01-06 00:55:243734// Test that we don't pass extraneous headers from the proxy's response to the
3735// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013736TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243737 HttpRequestInfo request;
3738 request.method = "GET";
bncce36dca22015-04-21 22:11:233739 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243740
3741 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033742 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243743
danakj1fd259a02016-04-16 03:17:093744 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243745
bnc691fda62016-08-12 00:43:163746 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243747
3748 // Since we have proxy, should try to establish tunnel.
3749 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173750 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3751 "Host: www.example.org:443\r\n"
3752 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243753 };
3754
3755 // The proxy responds to the connect with a 407.
3756 MockRead data_reads[] = {
3757 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3758 MockRead("X-Foo: bar\r\n"),
3759 MockRead("Set-Cookie: foo=bar\r\n"),
3760 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3761 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233762 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243763 };
3764
3765 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3766 arraysize(data_writes));
3767 session_deps_.socket_factory->AddSocketDataProvider(&data);
3768
3769 TestCompletionCallback callback;
3770
tfarina42834112016-09-22 13:38:203771 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013772 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243773
3774 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013775 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243776
bnc691fda62016-08-12 00:43:163777 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243778 ASSERT_TRUE(response);
3779 ASSERT_TRUE(response->headers);
3780 EXPECT_TRUE(response->headers->IsKeepAlive());
3781 EXPECT_EQ(407, response->headers->response_code());
3782 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3783 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3784 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3785
3786 std::string response_data;
bnc691fda62016-08-12 00:43:163787 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013788 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243789
3790 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3791 session->CloseAllConnections();
3792}
3793
[email protected]8fdbcd22010-05-05 02:54:523794// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3795// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013796TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523797 HttpRequestInfo request;
3798 request.method = "GET";
bncce36dca22015-04-21 22:11:233799 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523800
[email protected]cb9bf6ca2011-01-28 13:15:273801 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093802 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163803 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273804
[email protected]8fdbcd22010-05-05 02:54:523805 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233806 MockWrite(
3807 "GET / HTTP/1.1\r\n"
3808 "Host: www.example.org\r\n"
3809 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523810 };
3811
3812 MockRead data_reads1[] = {
3813 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3814 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3815 // Large content-length -- won't matter, as connection will be reset.
3816 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063817 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523818 };
3819
3820 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3821 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073822 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523823
[email protected]49639fa2011-12-20 23:22:413824 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523825
tfarina42834112016-09-22 13:38:203826 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013827 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523828
3829 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013830 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523831}
3832
[email protected]7a67a8152010-11-05 18:31:103833// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3834// through a non-authenticating proxy. The request should fail with
3835// ERR_UNEXPECTED_PROXY_AUTH.
3836// Note that it is impossible to detect if an HTTP server returns a 407 through
3837// a non-authenticating proxy - there is nothing to indicate whether the
3838// response came from the proxy or the server, so it is treated as if the proxy
3839// issued the challenge.
bncd16676a2016-07-20 16:23:013840TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273841 HttpRequestInfo request;
3842 request.method = "GET";
bncce36dca22015-04-21 22:11:233843 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273844
rdsmith82957ad2015-09-16 19:42:033845 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513846 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073847 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093848 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103849
[email protected]7a67a8152010-11-05 18:31:103850 // Since we have proxy, should try to establish tunnel.
3851 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173852 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3853 "Host: www.example.org:443\r\n"
3854 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103855
rsleevidb16bb02015-11-12 23:47:173856 MockWrite("GET / HTTP/1.1\r\n"
3857 "Host: www.example.org\r\n"
3858 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103859 };
3860
3861 MockRead data_reads1[] = {
3862 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3863
3864 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3865 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3866 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063867 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103868 };
3869
3870 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3871 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073872 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063873 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073874 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103875
[email protected]49639fa2011-12-20 23:22:413876 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103877
bnc691fda62016-08-12 00:43:163878 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103879
bnc691fda62016-08-12 00:43:163880 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103882
3883 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013884 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463885 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403886 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103887 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003888 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3889 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103890 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403891 entries, pos,
mikecirone8b85c432016-09-08 19:11:003892 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3893 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103894}
[email protected]2df19bb2010-08-25 20:13:463895
mmenke2a1781d2015-10-07 19:25:333896// Test a proxy auth scheme that allows default credentials and a proxy server
3897// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013898TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333899 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3900 HttpRequestInfo request;
3901 request.method = "GET";
3902 request.url = GURL("https://www.example.org/");
3903
3904 // Configure against proxy server "myproxy:70".
3905 session_deps_.proxy_service =
3906 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3907
Jeremy Roman0579ed62017-08-29 15:56:193908 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333909 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:193910 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333911 mock_handler->set_allows_default_credentials(true);
3912 auth_handler_factory->AddMockHandler(mock_handler.release(),
3913 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483914 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333915
3916 // Add NetLog just so can verify load timing information gets a NetLog ID.
3917 NetLog net_log;
3918 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093919 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333920
3921 // Since we have proxy, should try to establish tunnel.
3922 MockWrite data_writes1[] = {
3923 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173924 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333925 "Proxy-Connection: keep-alive\r\n\r\n"),
3926 };
3927
3928 // The proxy responds to the connect with a 407, using a non-persistent
3929 // connection.
3930 MockRead data_reads1[] = {
3931 // No credentials.
3932 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3933 MockRead("Proxy-Authenticate: Mock\r\n"),
3934 MockRead("Proxy-Connection: close\r\n\r\n"),
3935 };
3936
3937 // Since the first connection couldn't be reused, need to establish another
3938 // once given credentials.
3939 MockWrite data_writes2[] = {
3940 // After calling trans->RestartWithAuth(), this is the request we should
3941 // be issuing -- the final header line contains the credentials.
3942 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173943 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333944 "Proxy-Connection: keep-alive\r\n"
3945 "Proxy-Authorization: auth_token\r\n\r\n"),
3946
3947 MockWrite("GET / HTTP/1.1\r\n"
3948 "Host: www.example.org\r\n"
3949 "Connection: keep-alive\r\n\r\n"),
3950 };
3951
3952 MockRead data_reads2[] = {
3953 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3954
3955 MockRead("HTTP/1.1 200 OK\r\n"),
3956 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3957 MockRead("Content-Length: 5\r\n\r\n"),
3958 MockRead(SYNCHRONOUS, "hello"),
3959 };
3960
3961 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3962 data_writes1, arraysize(data_writes1));
3963 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3964 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3965 data_writes2, arraysize(data_writes2));
3966 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3967 SSLSocketDataProvider ssl(ASYNC, OK);
3968 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3969
bnc87dcefc2017-05-25 12:47:583970 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193971 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:333972
3973 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:203974 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013975 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333976
3977 const HttpResponseInfo* response = trans->GetResponseInfo();
3978 ASSERT_TRUE(response);
3979 ASSERT_TRUE(response->headers);
3980 EXPECT_FALSE(response->headers->IsKeepAlive());
3981 EXPECT_EQ(407, response->headers->response_code());
3982 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3983 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523984 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333985
3986 LoadTimingInfo load_timing_info;
3987 // CONNECT requests and responses are handled at the connect job level, so
3988 // the transaction does not yet have a connection.
3989 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3990
3991 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:013992 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:333993 response = trans->GetResponseInfo();
3994 ASSERT_TRUE(response);
3995 ASSERT_TRUE(response->headers);
3996 EXPECT_TRUE(response->headers->IsKeepAlive());
3997 EXPECT_EQ(200, response->headers->response_code());
3998 EXPECT_EQ(5, response->headers->GetContentLength());
3999 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4000
4001 // The password prompt info should not be set.
4002 EXPECT_FALSE(response->auth_challenge);
4003
4004 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4005 TestLoadTimingNotReusedWithPac(load_timing_info,
4006 CONNECT_TIMING_HAS_SSL_TIMES);
4007
4008 trans.reset();
4009 session->CloseAllConnections();
4010}
4011
4012// Test a proxy auth scheme that allows default credentials and a proxy server
4013// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014014TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334015 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4016 HttpRequestInfo request;
4017 request.method = "GET";
4018 request.url = GURL("https://www.example.org/");
4019
4020 // Configure against proxy server "myproxy:70".
4021 session_deps_.proxy_service =
4022 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4023
Jeremy Roman0579ed62017-08-29 15:56:194024 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334025 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194026 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334027 mock_handler->set_allows_default_credentials(true);
4028 auth_handler_factory->AddMockHandler(mock_handler.release(),
4029 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484030 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334031
4032 // Add NetLog just so can verify load timing information gets a NetLog ID.
4033 NetLog net_log;
4034 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094035 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334036
4037 // Should try to establish tunnel.
4038 MockWrite data_writes1[] = {
4039 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174040 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334041 "Proxy-Connection: keep-alive\r\n\r\n"),
4042
4043 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174044 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334045 "Proxy-Connection: keep-alive\r\n"
4046 "Proxy-Authorization: auth_token\r\n\r\n"),
4047 };
4048
4049 // The proxy responds to the connect with a 407, using a non-persistent
4050 // connection.
4051 MockRead data_reads1[] = {
4052 // No credentials.
4053 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4054 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4055 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4056 };
4057
4058 // Since the first connection was closed, need to establish another once given
4059 // credentials.
4060 MockWrite data_writes2[] = {
4061 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174062 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334063 "Proxy-Connection: keep-alive\r\n"
4064 "Proxy-Authorization: auth_token\r\n\r\n"),
4065
4066 MockWrite("GET / HTTP/1.1\r\n"
4067 "Host: www.example.org\r\n"
4068 "Connection: keep-alive\r\n\r\n"),
4069 };
4070
4071 MockRead data_reads2[] = {
4072 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4073
4074 MockRead("HTTP/1.1 200 OK\r\n"),
4075 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4076 MockRead("Content-Length: 5\r\n\r\n"),
4077 MockRead(SYNCHRONOUS, "hello"),
4078 };
4079
4080 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4081 data_writes1, arraysize(data_writes1));
4082 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4083 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4084 data_writes2, arraysize(data_writes2));
4085 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4086 SSLSocketDataProvider ssl(ASYNC, OK);
4087 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4088
bnc87dcefc2017-05-25 12:47:584089 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194090 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334091
4092 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204093 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014094 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334095
4096 const HttpResponseInfo* response = trans->GetResponseInfo();
4097 ASSERT_TRUE(response);
4098 ASSERT_TRUE(response->headers);
4099 EXPECT_TRUE(response->headers->IsKeepAlive());
4100 EXPECT_EQ(407, response->headers->response_code());
4101 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4102 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4103 EXPECT_FALSE(response->auth_challenge);
4104
4105 LoadTimingInfo load_timing_info;
4106 // CONNECT requests and responses are handled at the connect job level, so
4107 // the transaction does not yet have a connection.
4108 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4109
4110 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014111 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334112
4113 response = trans->GetResponseInfo();
4114 ASSERT_TRUE(response);
4115 ASSERT_TRUE(response->headers);
4116 EXPECT_TRUE(response->headers->IsKeepAlive());
4117 EXPECT_EQ(200, response->headers->response_code());
4118 EXPECT_EQ(5, response->headers->GetContentLength());
4119 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4120
4121 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524122 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334123
4124 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4125 TestLoadTimingNotReusedWithPac(load_timing_info,
4126 CONNECT_TIMING_HAS_SSL_TIMES);
4127
4128 trans.reset();
4129 session->CloseAllConnections();
4130}
4131
4132// Test a proxy auth scheme that allows default credentials and a proxy server
4133// that hangs up when credentials are initially sent, and hangs up again when
4134// they are retried.
bncd16676a2016-07-20 16:23:014135TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334136 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4137 HttpRequestInfo request;
4138 request.method = "GET";
4139 request.url = GURL("https://www.example.org/");
4140
4141 // Configure against proxy server "myproxy:70".
4142 session_deps_.proxy_service =
4143 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4144
Jeremy Roman0579ed62017-08-29 15:56:194145 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334146 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194147 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334148 mock_handler->set_allows_default_credentials(true);
4149 auth_handler_factory->AddMockHandler(mock_handler.release(),
4150 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484151 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334152
4153 // Add NetLog just so can verify load timing information gets a NetLog ID.
4154 NetLog net_log;
4155 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094156 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334157
4158 // Should try to establish tunnel.
4159 MockWrite data_writes1[] = {
4160 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174161 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334162 "Proxy-Connection: keep-alive\r\n\r\n"),
4163
4164 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174165 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334166 "Proxy-Connection: keep-alive\r\n"
4167 "Proxy-Authorization: auth_token\r\n\r\n"),
4168 };
4169
4170 // The proxy responds to the connect with a 407, and then hangs up after the
4171 // second request is sent.
4172 MockRead data_reads1[] = {
4173 // No credentials.
4174 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4175 MockRead("Content-Length: 0\r\n"),
4176 MockRead("Proxy-Connection: keep-alive\r\n"),
4177 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4178 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4179 };
4180
4181 // HttpNetworkTransaction sees a reused connection that was closed with
4182 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4183 // request.
4184 MockWrite data_writes2[] = {
4185 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174186 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334187 "Proxy-Connection: keep-alive\r\n\r\n"),
4188 };
4189
4190 // The proxy, having had more than enough of us, just hangs up.
4191 MockRead data_reads2[] = {
4192 // No credentials.
4193 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4194 };
4195
4196 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4197 data_writes1, arraysize(data_writes1));
4198 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4199 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4200 data_writes2, arraysize(data_writes2));
4201 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4202
bnc87dcefc2017-05-25 12:47:584203 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194204 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334205
4206 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204207 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014208 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334209
4210 const HttpResponseInfo* response = trans->GetResponseInfo();
4211 ASSERT_TRUE(response);
4212 ASSERT_TRUE(response->headers);
4213 EXPECT_TRUE(response->headers->IsKeepAlive());
4214 EXPECT_EQ(407, response->headers->response_code());
4215 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4216 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4217 EXPECT_FALSE(response->auth_challenge);
4218
4219 LoadTimingInfo load_timing_info;
4220 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4221
4222 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014223 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334224
4225 trans.reset();
4226 session->CloseAllConnections();
4227}
4228
4229// Test a proxy auth scheme that allows default credentials and a proxy server
4230// that hangs up when credentials are initially sent, and sends a challenge
4231// again they are retried.
bncd16676a2016-07-20 16:23:014232TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334233 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4234 HttpRequestInfo request;
4235 request.method = "GET";
4236 request.url = GURL("https://www.example.org/");
4237
4238 // Configure against proxy server "myproxy:70".
4239 session_deps_.proxy_service =
4240 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4241
Jeremy Roman0579ed62017-08-29 15:56:194242 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334243 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194244 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334245 mock_handler->set_allows_default_credentials(true);
4246 auth_handler_factory->AddMockHandler(mock_handler.release(),
4247 HttpAuth::AUTH_PROXY);
4248 // Add another handler for the second challenge. It supports default
4249 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194250 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334251 mock_handler->set_allows_default_credentials(true);
4252 auth_handler_factory->AddMockHandler(mock_handler.release(),
4253 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484254 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334255
4256 // Add NetLog just so can verify load timing information gets a NetLog ID.
4257 NetLog net_log;
4258 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094259 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334260
4261 // Should try to establish tunnel.
4262 MockWrite data_writes1[] = {
4263 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174264 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334265 "Proxy-Connection: keep-alive\r\n\r\n"),
4266 };
4267
4268 // The proxy responds to the connect with a 407, using a non-persistent
4269 // connection.
4270 MockRead data_reads1[] = {
4271 // No credentials.
4272 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4273 MockRead("Proxy-Authenticate: Mock\r\n"),
4274 MockRead("Proxy-Connection: close\r\n\r\n"),
4275 };
4276
4277 // Since the first connection was closed, need to establish another once given
4278 // credentials.
4279 MockWrite data_writes2[] = {
4280 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174281 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334282 "Proxy-Connection: keep-alive\r\n"
4283 "Proxy-Authorization: auth_token\r\n\r\n"),
4284 };
4285
4286 MockRead data_reads2[] = {
4287 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4288 MockRead("Proxy-Authenticate: Mock\r\n"),
4289 MockRead("Proxy-Connection: close\r\n\r\n"),
4290 };
4291
4292 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4293 data_writes1, arraysize(data_writes1));
4294 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4295 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4296 data_writes2, arraysize(data_writes2));
4297 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4298 SSLSocketDataProvider ssl(ASYNC, OK);
4299 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4300
bnc87dcefc2017-05-25 12:47:584301 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194302 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334303
4304 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204305 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014306 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334307
4308 const HttpResponseInfo* response = trans->GetResponseInfo();
4309 ASSERT_TRUE(response);
4310 ASSERT_TRUE(response->headers);
4311 EXPECT_EQ(407, response->headers->response_code());
4312 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4313 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4314 EXPECT_FALSE(response->auth_challenge);
4315
4316 LoadTimingInfo load_timing_info;
4317 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4318
4319 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014320 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334321 response = trans->GetResponseInfo();
4322 ASSERT_TRUE(response);
4323 ASSERT_TRUE(response->headers);
4324 EXPECT_EQ(407, response->headers->response_code());
4325 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4326 EXPECT_TRUE(response->auth_challenge);
4327
4328 trans.reset();
4329 session->CloseAllConnections();
4330}
4331
asankae2257db2016-10-11 22:03:164332// A more nuanced test than GenerateAuthToken test which asserts that
4333// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4334// unnecessarily invalidated, and that if the server co-operates, the
4335// authentication handshake can continue with the same scheme but with a
4336// different identity.
4337TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4338 HttpRequestInfo request;
4339 request.method = "GET";
4340 request.url = GURL("http://www.example.org/");
4341
Jeremy Roman0579ed62017-08-29 15:56:194342 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164343 auth_handler_factory->set_do_init_from_challenge(true);
4344
4345 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194346 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164347 mock_handler->set_allows_default_credentials(true);
4348 mock_handler->set_allows_explicit_credentials(true);
4349 mock_handler->set_connection_based(true);
4350 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4351 auth_handler_factory->AddMockHandler(mock_handler.release(),
4352 HttpAuth::AUTH_SERVER);
4353
4354 // Add another handler for the second challenge. It supports default
4355 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194356 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164357 mock_handler->set_allows_default_credentials(true);
4358 mock_handler->set_allows_explicit_credentials(true);
4359 mock_handler->set_connection_based(true);
4360 auth_handler_factory->AddMockHandler(mock_handler.release(),
4361 HttpAuth::AUTH_SERVER);
4362 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4363
4364 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4365
4366 MockWrite data_writes1[] = {
4367 MockWrite("GET / HTTP/1.1\r\n"
4368 "Host: www.example.org\r\n"
4369 "Connection: keep-alive\r\n\r\n"),
4370 };
4371
4372 MockRead data_reads1[] = {
4373 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4374 "WWW-Authenticate: Mock\r\n"
4375 "Connection: keep-alive\r\n\r\n"),
4376 };
4377
4378 // Identical to data_writes1[]. The AuthHandler encounters a
4379 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4380 // transaction procceds without an authorization header.
4381 MockWrite data_writes2[] = {
4382 MockWrite("GET / HTTP/1.1\r\n"
4383 "Host: www.example.org\r\n"
4384 "Connection: keep-alive\r\n\r\n"),
4385 };
4386
4387 MockRead data_reads2[] = {
4388 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4389 "WWW-Authenticate: Mock\r\n"
4390 "Connection: keep-alive\r\n\r\n"),
4391 };
4392
4393 MockWrite data_writes3[] = {
4394 MockWrite("GET / HTTP/1.1\r\n"
4395 "Host: www.example.org\r\n"
4396 "Connection: keep-alive\r\n"
4397 "Authorization: auth_token\r\n\r\n"),
4398 };
4399
4400 MockRead data_reads3[] = {
4401 MockRead("HTTP/1.1 200 OK\r\n"
4402 "Content-Length: 5\r\n"
4403 "Content-Type: text/plain\r\n"
4404 "Connection: keep-alive\r\n\r\n"
4405 "Hello"),
4406 };
4407
4408 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4409 data_writes1, arraysize(data_writes1));
4410 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4411
4412 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4413 data_writes2, arraysize(data_writes2));
4414 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4415
4416 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4417 data_writes3, arraysize(data_writes3));
4418 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4419
bnc87dcefc2017-05-25 12:47:584420 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194421 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164422
4423 TestCompletionCallback callback;
4424 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4425 EXPECT_THAT(callback.GetResult(rv), IsOk());
4426
4427 const HttpResponseInfo* response = trans->GetResponseInfo();
4428 ASSERT_TRUE(response);
4429 ASSERT_TRUE(response->headers);
4430 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4431
4432 // The following three tests assert that an authentication challenge was
4433 // received and that the stack is ready to respond to the challenge using
4434 // ambient credentials.
4435 EXPECT_EQ(401, response->headers->response_code());
4436 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4437 EXPECT_FALSE(response->auth_challenge);
4438
4439 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4440 EXPECT_THAT(callback.GetResult(rv), IsOk());
4441 response = trans->GetResponseInfo();
4442 ASSERT_TRUE(response);
4443 ASSERT_TRUE(response->headers);
4444
4445 // The following three tests assert that an authentication challenge was
4446 // received and that the stack needs explicit credentials before it is ready
4447 // to respond to the challenge.
4448 EXPECT_EQ(401, response->headers->response_code());
4449 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4450 EXPECT_TRUE(response->auth_challenge);
4451
4452 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4453 EXPECT_THAT(callback.GetResult(rv), IsOk());
4454 response = trans->GetResponseInfo();
4455 ASSERT_TRUE(response);
4456 ASSERT_TRUE(response->headers);
4457 EXPECT_EQ(200, response->headers->response_code());
4458
4459 trans.reset();
4460 session->CloseAllConnections();
4461}
4462
[email protected]029c83b62013-01-24 05:28:204463// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014464TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204465 HttpRequestInfo request1;
4466 request1.method = "GET";
bncce36dca22015-04-21 22:11:234467 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204468
4469 HttpRequestInfo request2;
4470 request2.method = "GET";
bncce36dca22015-04-21 22:11:234471 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204472
4473 // Configure against proxy server "myproxy:70".
brettwc1213d92016-11-12 03:41:134474 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:514475 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074476 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094477 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204478
4479 // Since we have proxy, should try to establish tunnel.
4480 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174481 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4482 "Host: www.example.org:443\r\n"
4483 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204484
rsleevidb16bb02015-11-12 23:47:174485 MockWrite("GET /1 HTTP/1.1\r\n"
4486 "Host: www.example.org\r\n"
4487 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204488
rsleevidb16bb02015-11-12 23:47:174489 MockWrite("GET /2 HTTP/1.1\r\n"
4490 "Host: www.example.org\r\n"
4491 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204492 };
4493
4494 // The proxy responds to the connect with a 407, using a persistent
4495 // connection.
4496 MockRead data_reads1[] = {
4497 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4498
4499 MockRead("HTTP/1.1 200 OK\r\n"),
4500 MockRead("Content-Length: 1\r\n\r\n"),
4501 MockRead(SYNCHRONOUS, "1"),
4502
4503 MockRead("HTTP/1.1 200 OK\r\n"),
4504 MockRead("Content-Length: 2\r\n\r\n"),
4505 MockRead(SYNCHRONOUS, "22"),
4506 };
4507
4508 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4509 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074510 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204511 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074512 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204513
4514 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584515 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194516 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204517
4518 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014519 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204520
4521 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014522 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204523
4524 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524525 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474526 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524527 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204528 EXPECT_EQ(1, response1->headers->GetContentLength());
4529
4530 LoadTimingInfo load_timing_info1;
4531 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4532 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4533
4534 trans1.reset();
4535
4536 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584537 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194538 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204539
4540 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014541 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204542
4543 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014544 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204545
4546 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524547 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474548 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524549 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204550 EXPECT_EQ(2, response2->headers->GetContentLength());
4551
4552 LoadTimingInfo load_timing_info2;
4553 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4554 TestLoadTimingReused(load_timing_info2);
4555
4556 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4557
4558 trans2.reset();
4559 session->CloseAllConnections();
4560}
4561
4562// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014563TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204564 HttpRequestInfo request1;
4565 request1.method = "GET";
bncce36dca22015-04-21 22:11:234566 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204567
4568 HttpRequestInfo request2;
4569 request2.method = "GET";
bncce36dca22015-04-21 22:11:234570 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204571
4572 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034573 session_deps_.proxy_service =
4574 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514575 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074576 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094577 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204578
4579 // Since we have proxy, should try to establish tunnel.
4580 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174581 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4582 "Host: www.example.org:443\r\n"
4583 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204584
rsleevidb16bb02015-11-12 23:47:174585 MockWrite("GET /1 HTTP/1.1\r\n"
4586 "Host: www.example.org\r\n"
4587 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204588
rsleevidb16bb02015-11-12 23:47:174589 MockWrite("GET /2 HTTP/1.1\r\n"
4590 "Host: www.example.org\r\n"
4591 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204592 };
4593
4594 // The proxy responds to the connect with a 407, using a persistent
4595 // connection.
4596 MockRead data_reads1[] = {
4597 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4598
4599 MockRead("HTTP/1.1 200 OK\r\n"),
4600 MockRead("Content-Length: 1\r\n\r\n"),
4601 MockRead(SYNCHRONOUS, "1"),
4602
4603 MockRead("HTTP/1.1 200 OK\r\n"),
4604 MockRead("Content-Length: 2\r\n\r\n"),
4605 MockRead(SYNCHRONOUS, "22"),
4606 };
4607
4608 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4609 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074610 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204611 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074612 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204613
4614 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584615 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194616 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204617
4618 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204620
4621 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014622 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204623
4624 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524625 ASSERT_TRUE(response1);
4626 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204627 EXPECT_EQ(1, response1->headers->GetContentLength());
4628
4629 LoadTimingInfo load_timing_info1;
4630 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4631 TestLoadTimingNotReusedWithPac(load_timing_info1,
4632 CONNECT_TIMING_HAS_SSL_TIMES);
4633
4634 trans1.reset();
4635
4636 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584637 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194638 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204639
4640 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204642
4643 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014644 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204645
4646 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524647 ASSERT_TRUE(response2);
4648 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204649 EXPECT_EQ(2, response2->headers->GetContentLength());
4650
4651 LoadTimingInfo load_timing_info2;
4652 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4653 TestLoadTimingReusedWithPac(load_timing_info2);
4654
4655 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4656
4657 trans2.reset();
4658 session->CloseAllConnections();
4659}
4660
[email protected]2df19bb2010-08-25 20:13:464661// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014662TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274663 HttpRequestInfo request;
4664 request.method = "GET";
bncce36dca22015-04-21 22:11:234665 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274666
[email protected]2df19bb2010-08-25 20:13:464667 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034668 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514669 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074670 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464672
[email protected]2df19bb2010-08-25 20:13:464673 // Since we have proxy, should use full url
4674 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234675 MockWrite(
4676 "GET http://www.example.org/ HTTP/1.1\r\n"
4677 "Host: www.example.org\r\n"
4678 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464679 };
4680
4681 MockRead data_reads1[] = {
4682 MockRead("HTTP/1.1 200 OK\r\n"),
4683 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4684 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064685 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464686 };
4687
4688 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4689 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074690 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064691 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074692 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464693
[email protected]49639fa2011-12-20 23:22:414694 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464695
bnc691fda62016-08-12 00:43:164696 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504697
bnc691fda62016-08-12 00:43:164698 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464700
4701 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014702 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464703
[email protected]58e32bb2013-01-21 18:23:254704 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164705 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254706 TestLoadTimingNotReused(load_timing_info,
4707 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4708
bnc691fda62016-08-12 00:43:164709 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524710 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464711
tbansal2ecbbc72016-10-06 17:15:474712 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:464713 EXPECT_TRUE(response->headers->IsKeepAlive());
4714 EXPECT_EQ(200, response->headers->response_code());
4715 EXPECT_EQ(100, response->headers->GetContentLength());
4716 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4717
4718 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524719 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464720}
4721
[email protected]7642b5ae2010-09-01 20:55:174722// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014723TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274724 HttpRequestInfo request;
4725 request.method = "GET";
bncce36dca22015-04-21 22:11:234726 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274727
[email protected]7642b5ae2010-09-01 20:55:174728 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034729 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514730 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074731 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094732 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174733
bncce36dca22015-04-21 22:11:234734 // fetch http://www.example.org/ via SPDY
bncdf80d44fd2016-07-15 20:27:414735 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454736 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414737 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174738
bnc42331402016-07-25 13:36:154739 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:414740 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174741 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414742 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174743 };
4744
rch8e6c6c42015-05-01 14:05:134745 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4746 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074747 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174748
[email protected]8ddf8322012-02-23 18:08:064749 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364750 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074751 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174752
[email protected]49639fa2011-12-20 23:22:414753 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174754
bnc691fda62016-08-12 00:43:164755 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504756
bnc691fda62016-08-12 00:43:164757 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014758 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:174759
4760 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014761 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:174762
[email protected]58e32bb2013-01-21 18:23:254763 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164764 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254765 TestLoadTimingNotReused(load_timing_info,
4766 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4767
bnc691fda62016-08-12 00:43:164768 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524769 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:474770 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:524771 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024772 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174773
4774 std::string response_data;
bnc691fda62016-08-12 00:43:164775 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:234776 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174777}
4778
[email protected]1c173852014-06-19 12:51:504779// Verifies that a session which races and wins against the owning transaction
4780// (completing prior to host resolution), doesn't fail the transaction.
4781// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:014782TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:504783 HttpRequestInfo request;
4784 request.method = "GET";
bncce36dca22015-04-21 22:11:234785 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504786
4787 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034788 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514789 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504790 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094791 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504792
bncce36dca22015-04-21 22:11:234793 // Fetch http://www.example.org/ through the SPDY proxy.
bncdf80d44fd2016-07-15 20:27:414794 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:454795 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:414796 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:504797
bnc42331402016-07-25 13:36:154798 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:414799 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:504800 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414801 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504802 };
4803
rch8e6c6c42015-05-01 14:05:134804 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4805 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504806 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4807
4808 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364809 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:504810 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4811
4812 TestCompletionCallback callback1;
4813
bnc691fda62016-08-12 00:43:164814 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:504815
4816 // Stall the hostname resolution begun by the transaction.
4817 session_deps_.host_resolver->set_synchronous_mode(false);
4818 session_deps_.host_resolver->set_ondemand_mode(true);
4819
bnc691fda62016-08-12 00:43:164820 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014821 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:504822
4823 // Race a session to the proxy, which completes first.
4824 session_deps_.host_resolver->set_ondemand_mode(false);
4825 SpdySessionKey key(
4826 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4827 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:524828 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504829
4830 // Unstall the resolution begun by the transaction.
4831 session_deps_.host_resolver->set_ondemand_mode(true);
4832 session_deps_.host_resolver->ResolveAllPending();
4833
4834 EXPECT_FALSE(callback1.have_result());
4835 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014836 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:504837
bnc691fda62016-08-12 00:43:164838 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:524839 ASSERT_TRUE(response);
4840 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024841 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504842
4843 std::string response_data;
bnc691fda62016-08-12 00:43:164844 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:504845 EXPECT_EQ(kUploadData, response_data);
4846}
4847
[email protected]dc7bd1c52010-11-12 00:01:134848// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014849TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274850 HttpRequestInfo request;
4851 request.method = "GET";
bncce36dca22015-04-21 22:11:234852 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274853
[email protected]79cb5c12011-09-12 13:12:044854 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034855 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514856 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074857 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134859
[email protected]dc7bd1c52010-11-12 00:01:134860 // The first request will be a bare GET, the second request will be a
4861 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:454862 spdy_util_.set_default_url(request.url);
bncdf80d44fd2016-07-15 20:27:414863 SpdySerializedFrame req_get(
bnc38dcd392016-02-09 23:19:494864 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384865 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134866 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464867 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134868 };
bncdf80d44fd2016-07-15 20:27:414869 SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
4870 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
4871 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134872 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414873 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134874 };
4875
4876 // The first response is a 407 proxy authentication challenge, and the second
4877 // response will be a 200 response since the second request includes a valid
4878 // Authorization header.
4879 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464880 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134881 };
bnc42331402016-07-25 13:36:154882 SpdySerializedFrame resp_authentication(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:234883 "407", kExtraAuthenticationHeaders,
bncdf80d44fd2016-07-15 20:27:414884 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4885 SpdySerializedFrame body_authentication(
4886 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:154887 SpdySerializedFrame resp_data(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:414888 SpdySerializedFrame body_data(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134889 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414890 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:464891 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:414892 CreateMockRead(resp_data, 4),
4893 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:134894 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134895 };
4896
rch8e6c6c42015-05-01 14:05:134897 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4898 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074899 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134900
[email protected]8ddf8322012-02-23 18:08:064901 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364902 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074903 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134904
[email protected]49639fa2011-12-20 23:22:414905 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134906
bnc691fda62016-08-12 00:43:164907 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:134908
bnc691fda62016-08-12 00:43:164909 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014910 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134911
4912 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014913 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134914
bnc691fda62016-08-12 00:43:164915 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134916
wezca1070932016-05-26 20:30:524917 ASSERT_TRUE(response);
4918 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134919 EXPECT_EQ(407, response->headers->response_code());
4920 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434921 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134922
[email protected]49639fa2011-12-20 23:22:414923 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134924
bnc691fda62016-08-12 00:43:164925 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:014926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:134927
4928 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014929 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:134930
bnc691fda62016-08-12 00:43:164931 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:134932
wezca1070932016-05-26 20:30:524933 ASSERT_TRUE(response_restart);
4934 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134935 EXPECT_EQ(200, response_restart->headers->response_code());
4936 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524937 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134938}
4939
[email protected]d9da5fe2010-10-13 22:37:164940// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:014941TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274942 HttpRequestInfo request;
4943 request.method = "GET";
bncce36dca22015-04-21 22:11:234944 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274945
[email protected]d9da5fe2010-10-13 22:37:164946 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034947 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514948 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074949 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094950 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164951
bnc691fda62016-08-12 00:43:164952 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:164953
bncce36dca22015-04-21 22:11:234954 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:414955 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234956 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4957 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164958
bncce36dca22015-04-21 22:11:234959 const char get[] =
4960 "GET / HTTP/1.1\r\n"
4961 "Host: www.example.org\r\n"
4962 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414963 SpdySerializedFrame wrapped_get(
4964 spdy_util_.ConstructSpdyDataFrame(1, get, strlen(get), false));
bnc42331402016-07-25 13:36:154965 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164966 const char resp[] = "HTTP/1.1 200 OK\r\n"
4967 "Content-Length: 10\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:414968 SpdySerializedFrame wrapped_get_resp(
4969 spdy_util_.ConstructSpdyDataFrame(1, resp, strlen(resp), false));
4970 SpdySerializedFrame wrapped_body(
4971 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", 10, false));
4972 SpdySerializedFrame window_update(
4973 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:044974
4975 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:414976 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
4977 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044978 };
4979
[email protected]d9da5fe2010-10-13 22:37:164980 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:414981 CreateMockRead(conn_resp, 1, ASYNC),
4982 CreateMockRead(wrapped_get_resp, 3, ASYNC),
4983 CreateMockRead(wrapped_body, 4, ASYNC),
4984 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134985 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164986 };
4987
rch8e6c6c42015-05-01 14:05:134988 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4989 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074990 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164991
[email protected]8ddf8322012-02-23 18:08:064992 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:364993 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:074994 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064995 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074996 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164997
[email protected]49639fa2011-12-20 23:22:414998 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164999
bnc691fda62016-08-12 00:43:165000 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015001 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165002
5003 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015004 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165005
[email protected]58e32bb2013-01-21 18:23:255006 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165007 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255008 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5009
bnc691fda62016-08-12 00:43:165010 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525011 ASSERT_TRUE(response);
5012 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165013 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5014
5015 std::string response_data;
bnc691fda62016-08-12 00:43:165016 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165017 EXPECT_EQ("1234567890", response_data);
5018}
5019
5020// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015021TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5022 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385023
[email protected]cb9bf6ca2011-01-28 13:15:275024 HttpRequestInfo request;
5025 request.method = "GET";
bncce36dca22015-04-21 22:11:235026 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275027
[email protected]d9da5fe2010-10-13 22:37:165028 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035029 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515030 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075031 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165033
bnc691fda62016-08-12 00:43:165034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165035
bncce36dca22015-04-21 22:11:235036 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415037 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235038 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5039 // fetch https://www.example.org/ via SPDY
5040 const char kMyUrl[] = "https://www.example.org/";
bncdf80d44fd2016-07-15 20:27:415041 SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495042 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415043 SpdySerializedFrame wrapped_get(spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bnc42331402016-07-25 13:36:155044 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415045 SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155046 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415047 SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025048 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncdf80d44fd2016-07-15 20:27:415049 SpdySerializedFrame body(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5050 SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025051 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncdf80d44fd2016-07-15 20:27:415052 SpdySerializedFrame window_update_get_resp(
5053 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
5054 SpdySerializedFrame window_update_body(
5055 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045056
5057 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415058 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5059 CreateMockWrite(window_update_get_resp, 6),
5060 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045061 };
5062
[email protected]d9da5fe2010-10-13 22:37:165063 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415064 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095065 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415066 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5067 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135068 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165069 };
5070
rch32320842015-05-16 15:57:095071 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5072 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075073 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165074
[email protected]8ddf8322012-02-23 18:08:065075 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365076 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075077 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065078 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365079 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075080 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165081
[email protected]49639fa2011-12-20 23:22:415082 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165083
bnc691fda62016-08-12 00:43:165084 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015085 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165086
rch32320842015-05-16 15:57:095087 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555088 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095089 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595090 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165091 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015092 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165093
[email protected]58e32bb2013-01-21 18:23:255094 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165095 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255096 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5097
bnc691fda62016-08-12 00:43:165098 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525099 ASSERT_TRUE(response);
5100 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025101 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165102
5103 std::string response_data;
bnc691fda62016-08-12 00:43:165104 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235105 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165106}
5107
5108// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015109TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275110 HttpRequestInfo request;
5111 request.method = "GET";
bncce36dca22015-04-21 22:11:235112 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275113
[email protected]d9da5fe2010-10-13 22:37:165114 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035115 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515116 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075117 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165119
bnc691fda62016-08-12 00:43:165120 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165121
bncce36dca22015-04-21 22:11:235122 // CONNECT to www.example.org:443 via SPDY
bncdf80d44fd2016-07-15 20:27:415123 SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235124 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:415125 SpdySerializedFrame get(
diannahu9904e272017-02-03 14:40:085126 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165127
5128 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415129 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165130 };
5131
bnc42331402016-07-25 13:36:155132 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
bncdf80d44fd2016-07-15 20:27:415133 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165134 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415135 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165136 };
5137
rch8e6c6c42015-05-01 14:05:135138 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5139 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:075140 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165141
[email protected]8ddf8322012-02-23 18:08:065142 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365143 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075144 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065145 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365146 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075147 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165148
[email protected]49639fa2011-12-20 23:22:415149 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165150
bnc691fda62016-08-12 00:43:165151 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015152 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165153
5154 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015155 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165156
ttuttle960fcbf2016-04-19 13:26:325157 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165158}
5159
[email protected]f6c63db52013-02-02 00:35:225160// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5161// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015162TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225163 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5164 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035165 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515166 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075167 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095168 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505169 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225170
5171 HttpRequestInfo request1;
5172 request1.method = "GET";
bncce36dca22015-04-21 22:11:235173 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225174 request1.load_flags = 0;
5175
5176 HttpRequestInfo request2;
5177 request2.method = "GET";
bncce36dca22015-04-21 22:11:235178 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225179 request2.load_flags = 0;
5180
bncce36dca22015-04-21 22:11:235181 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415182 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235183 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155184 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225185
bncce36dca22015-04-21 22:11:235186 // Fetch https://www.example.org/ via HTTP.
5187 const char get1[] =
5188 "GET / HTTP/1.1\r\n"
5189 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225190 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415191 SpdySerializedFrame wrapped_get1(
5192 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225193 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5194 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415195 SpdySerializedFrame wrapped_get_resp1(
5196 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5197 SpdySerializedFrame wrapped_body1(
5198 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5199 SpdySerializedFrame window_update(
5200 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225201
bncce36dca22015-04-21 22:11:235202 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295203 SpdyHeaderBlock connect2_block;
5204 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnca9b9e222016-07-11 20:10:405205 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
bnc42331402016-07-25 13:36:155206 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
5207 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395208
bnc42331402016-07-25 13:36:155209 SpdySerializedFrame conn_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225210
bncce36dca22015-04-21 22:11:235211 // Fetch https://mail.example.org/ via HTTP.
5212 const char get2[] =
5213 "GET / HTTP/1.1\r\n"
5214 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225215 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415216 SpdySerializedFrame wrapped_get2(
5217 spdy_util_.ConstructSpdyDataFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225218 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5219 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415220 SpdySerializedFrame wrapped_get_resp2(
5221 spdy_util_.ConstructSpdyDataFrame(3, resp2, strlen(resp2), false));
5222 SpdySerializedFrame wrapped_body2(
5223 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225224
5225 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415226 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5227 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225228 };
5229
5230 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415231 CreateMockRead(conn_resp1, 1, ASYNC),
5232 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5233 CreateMockRead(wrapped_body1, 4, ASYNC),
5234 CreateMockRead(conn_resp2, 6, ASYNC),
5235 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5236 CreateMockRead(wrapped_body2, 9, ASYNC),
5237 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225238 };
5239
mmenke11eb5152015-06-09 14:50:505240 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5241 arraysize(spdy_writes));
5242 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225243
5244 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365245 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505246 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225247 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505248 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225249 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505250 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225251
5252 TestCompletionCallback callback;
5253
bnc691fda62016-08-12 00:43:165254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205255 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015256 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225257
5258 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165259 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225260 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5261
bnc691fda62016-08-12 00:43:165262 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525263 ASSERT_TRUE(response);
5264 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225265 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5266
5267 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295268 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
bnc691fda62016-08-12 00:43:165269 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505270 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225271
bnc691fda62016-08-12 00:43:165272 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205273 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015274 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225275
5276 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165277 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225278 // Even though the SPDY connection is reused, a new tunnelled connection has
5279 // to be created, so the socket's load timing looks like a fresh connection.
5280 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5281
5282 // The requests should have different IDs, since they each are using their own
5283 // separate stream.
5284 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5285
bnc691fda62016-08-12 00:43:165286 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505287 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225288}
5289
5290// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5291// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015292TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225293 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5294 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035295 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515296 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075297 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095298 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505299 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225300
5301 HttpRequestInfo request1;
5302 request1.method = "GET";
bncce36dca22015-04-21 22:11:235303 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225304 request1.load_flags = 0;
5305
5306 HttpRequestInfo request2;
5307 request2.method = "GET";
bncce36dca22015-04-21 22:11:235308 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225309 request2.load_flags = 0;
5310
bncce36dca22015-04-21 22:11:235311 // CONNECT to www.example.org:443 via SPDY.
bncdf80d44fd2016-07-15 20:27:415312 SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235313 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bnc42331402016-07-25 13:36:155314 SpdySerializedFrame conn_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225315
bncce36dca22015-04-21 22:11:235316 // Fetch https://www.example.org/ via HTTP.
5317 const char get1[] =
5318 "GET / HTTP/1.1\r\n"
5319 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225320 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415321 SpdySerializedFrame wrapped_get1(
5322 spdy_util_.ConstructSpdyDataFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225323 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5324 "Content-Length: 1\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415325 SpdySerializedFrame wrapped_get_resp1(
5326 spdy_util_.ConstructSpdyDataFrame(1, resp1, strlen(resp1), false));
5327 SpdySerializedFrame wrapped_body1(
5328 spdy_util_.ConstructSpdyDataFrame(1, "1", 1, false));
5329 SpdySerializedFrame window_update(
5330 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225331
bncce36dca22015-04-21 22:11:235332 // Fetch https://www.example.org/2 via HTTP.
5333 const char get2[] =
5334 "GET /2 HTTP/1.1\r\n"
5335 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225336 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415337 SpdySerializedFrame wrapped_get2(
5338 spdy_util_.ConstructSpdyDataFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225339 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5340 "Content-Length: 2\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:415341 SpdySerializedFrame wrapped_get_resp2(
5342 spdy_util_.ConstructSpdyDataFrame(1, resp2, strlen(resp2), false));
5343 SpdySerializedFrame wrapped_body2(
5344 spdy_util_.ConstructSpdyDataFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225345
5346 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415347 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5348 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225349 };
5350
5351 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415352 CreateMockRead(conn_resp1, 1, ASYNC),
5353 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465354 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415355 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465356 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415357 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225358 };
5359
mmenke11eb5152015-06-09 14:50:505360 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5361 arraysize(spdy_writes));
5362 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225363
5364 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365365 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225367 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225369
5370 TestCompletionCallback callback;
5371
bnc87dcefc2017-05-25 12:47:585372 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195373 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205374 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015375 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225376
5377 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015378 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225379
5380 LoadTimingInfo load_timing_info;
5381 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5382 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5383
5384 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525385 ASSERT_TRUE(response);
5386 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225387 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5388
5389 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295390 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505391 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225392 trans.reset();
5393
bnc87dcefc2017-05-25 12:47:585394 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195395 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205396 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015397 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225398
[email protected]f6c63db52013-02-02 00:35:225399 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015400 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225401
5402 LoadTimingInfo load_timing_info2;
5403 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5404 TestLoadTimingReused(load_timing_info2);
5405
5406 // The requests should have the same ID.
5407 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5408
[email protected]90499482013-06-01 00:39:505409 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225410}
5411
5412// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5413// Proxy to different servers.
bncd16676a2016-07-20 16:23:015414TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225415 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035416 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515417 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075418 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095419 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505420 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225421
5422 HttpRequestInfo request1;
5423 request1.method = "GET";
bncce36dca22015-04-21 22:11:235424 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225425 request1.load_flags = 0;
5426
5427 HttpRequestInfo request2;
5428 request2.method = "GET";
bncce36dca22015-04-21 22:11:235429 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225430 request2.load_flags = 0;
5431
bncce36dca22015-04-21 22:11:235432 // http://www.example.org/
bnc086b39e12016-06-24 13:05:265433 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235434 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:415435 SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155436 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
5437 SpdySerializedFrame get_resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:415438 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385439 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225440
bncce36dca22015-04-21 22:11:235441 // http://mail.example.org/
bnc086b39e12016-06-24 13:05:265442 SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235443 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncdf80d44fd2016-07-15 20:27:415444 SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155445 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
5446 SpdySerializedFrame get_resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:415447 SpdySerializedFrame body2(
5448 spdy_util_.ConstructSpdyDataFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225449
5450 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415451 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225452 };
5453
5454 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415455 CreateMockRead(get_resp1, 1, ASYNC),
5456 CreateMockRead(body1, 2, ASYNC),
5457 CreateMockRead(get_resp2, 4, ASYNC),
5458 CreateMockRead(body2, 5, ASYNC),
5459 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225460 };
5461
mmenke11eb5152015-06-09 14:50:505462 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5463 arraysize(spdy_writes));
5464 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225465
5466 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365467 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225469
5470 TestCompletionCallback callback;
5471
bnc87dcefc2017-05-25 12:47:585472 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195473 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205474 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015475 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225476
5477 LoadTimingInfo load_timing_info;
5478 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5479 TestLoadTimingNotReused(load_timing_info,
5480 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5481
5482 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525483 ASSERT_TRUE(response);
5484 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025485 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225486
5487 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295488 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505489 rv = trans->Read(buf.get(), 256, callback.callback());
5490 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225491 // Delete the first request, so the second one can reuse the socket.
5492 trans.reset();
5493
bnc691fda62016-08-12 00:43:165494 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205495 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015496 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225497
5498 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165499 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225500 TestLoadTimingReused(load_timing_info2);
5501
5502 // The requests should have the same ID.
5503 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5504
bnc691fda62016-08-12 00:43:165505 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505506 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225507}
5508
[email protected]2df19bb2010-08-25 20:13:465509// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015510TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465511 HttpRequestInfo request;
5512 request.method = "GET";
bncce36dca22015-04-21 22:11:235513 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465514 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295515 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465516
[email protected]79cb5c12011-09-12 13:12:045517 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035518 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515519 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075520 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095521 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275522
[email protected]2df19bb2010-08-25 20:13:465523 // Since we have proxy, should use full url
5524 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165525 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5526 "Host: www.example.org\r\n"
5527 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465528
bnc691fda62016-08-12 00:43:165529 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235530 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165531 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5532 "Host: www.example.org\r\n"
5533 "Proxy-Connection: keep-alive\r\n"
5534 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465535 };
5536
5537 // The proxy responds to the GET with a 407, using a persistent
5538 // connection.
5539 MockRead data_reads1[] = {
5540 // No credentials.
5541 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5542 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5543 MockRead("Proxy-Connection: keep-alive\r\n"),
5544 MockRead("Content-Length: 0\r\n\r\n"),
5545
5546 MockRead("HTTP/1.1 200 OK\r\n"),
5547 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5548 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065549 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465550 };
5551
5552 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5553 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075554 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065555 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075556 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465557
[email protected]49639fa2011-12-20 23:22:415558 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465559
bnc691fda62016-08-12 00:43:165560 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505561
bnc691fda62016-08-12 00:43:165562 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015563 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465564
5565 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015566 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465567
[email protected]58e32bb2013-01-21 18:23:255568 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165569 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255570 TestLoadTimingNotReused(load_timing_info,
5571 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5572
bnc691fda62016-08-12 00:43:165573 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525574 ASSERT_TRUE(response);
5575 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465576 EXPECT_EQ(407, response->headers->response_code());
5577 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435578 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465579
[email protected]49639fa2011-12-20 23:22:415580 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465581
bnc691fda62016-08-12 00:43:165582 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015583 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465584
5585 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015586 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465587
[email protected]58e32bb2013-01-21 18:23:255588 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165589 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255590 // Retrying with HTTP AUTH is considered to be reusing a socket.
5591 TestLoadTimingReused(load_timing_info);
5592
bnc691fda62016-08-12 00:43:165593 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525594 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465595
5596 EXPECT_TRUE(response->headers->IsKeepAlive());
5597 EXPECT_EQ(200, response->headers->response_code());
5598 EXPECT_EQ(100, response->headers->GetContentLength());
5599 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5600
5601 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525602 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465603}
5604
[email protected]23e482282013-06-14 16:08:025605void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085606 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425607 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085608 request.method = "GET";
bncce36dca22015-04-21 22:11:235609 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085610
[email protected]cb9bf6ca2011-01-28 13:15:275611 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035612 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095613 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275614
[email protected]c744cf22009-02-27 07:28:085615 // Since we have proxy, should try to establish tunnel.
5616 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175617 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5618 "Host: www.example.org:443\r\n"
5619 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085620 };
5621
5622 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235623 status, MockRead("Content-Length: 10\r\n\r\n"),
5624 // No response body because the test stops reading here.
5625 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085626 };
5627
[email protected]31a2bfe2010-02-09 08:03:395628 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5629 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075630 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085631
[email protected]49639fa2011-12-20 23:22:415632 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085633
bnc691fda62016-08-12 00:43:165634 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505635
tfarina42834112016-09-22 13:38:205636 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085638
5639 rv = callback.WaitForResult();
5640 EXPECT_EQ(expected_status, rv);
5641}
5642
[email protected]23e482282013-06-14 16:08:025643void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235644 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085645 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425646 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085647}
5648
bncd16676a2016-07-20 16:23:015649TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085650 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5651}
5652
bncd16676a2016-07-20 16:23:015653TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085654 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5655}
5656
bncd16676a2016-07-20 16:23:015657TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085658 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5659}
5660
bncd16676a2016-07-20 16:23:015661TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085662 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5663}
5664
bncd16676a2016-07-20 16:23:015665TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085666 ConnectStatusHelper(
5667 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5668}
5669
bncd16676a2016-07-20 16:23:015670TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085671 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5672}
5673
bncd16676a2016-07-20 16:23:015674TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085675 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5676}
5677
bncd16676a2016-07-20 16:23:015678TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085679 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5680}
5681
bncd16676a2016-07-20 16:23:015682TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085683 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5684}
5685
bncd16676a2016-07-20 16:23:015686TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085687 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5688}
5689
bncd16676a2016-07-20 16:23:015690TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085691 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5692}
5693
bncd16676a2016-07-20 16:23:015694TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085695 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5696}
5697
bncd16676a2016-07-20 16:23:015698TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085699 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5700}
5701
bncd16676a2016-07-20 16:23:015702TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085703 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5704}
5705
bncd16676a2016-07-20 16:23:015706TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085707 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5708}
5709
bncd16676a2016-07-20 16:23:015710TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085711 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5712}
5713
bncd16676a2016-07-20 16:23:015714TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:375715 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5716}
5717
bncd16676a2016-07-20 16:23:015718TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085719 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5720}
5721
bncd16676a2016-07-20 16:23:015722TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085723 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5724}
5725
bncd16676a2016-07-20 16:23:015726TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085727 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5728}
5729
bncd16676a2016-07-20 16:23:015730TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085731 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5732}
5733
bncd16676a2016-07-20 16:23:015734TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085735 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5736}
5737
bncd16676a2016-07-20 16:23:015738TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085739 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5740}
5741
bncd16676a2016-07-20 16:23:015742TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085743 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5744}
5745
bncd16676a2016-07-20 16:23:015746TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085747 ConnectStatusHelperWithExpectedStatus(
5748 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545749 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085750}
5751
bncd16676a2016-07-20 16:23:015752TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085753 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5754}
5755
bncd16676a2016-07-20 16:23:015756TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085757 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5758}
5759
bncd16676a2016-07-20 16:23:015760TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085761 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5762}
5763
bncd16676a2016-07-20 16:23:015764TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085765 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5766}
5767
bncd16676a2016-07-20 16:23:015768TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085769 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5770}
5771
bncd16676a2016-07-20 16:23:015772TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085773 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5774}
5775
bncd16676a2016-07-20 16:23:015776TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085777 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5778}
5779
bncd16676a2016-07-20 16:23:015780TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085781 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5782}
5783
bncd16676a2016-07-20 16:23:015784TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085785 ConnectStatusHelper(
5786 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5787}
5788
bncd16676a2016-07-20 16:23:015789TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085790 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5791}
5792
bncd16676a2016-07-20 16:23:015793TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085794 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5795}
5796
bncd16676a2016-07-20 16:23:015797TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085798 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5799}
5800
bncd16676a2016-07-20 16:23:015801TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085802 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5803}
5804
bncd16676a2016-07-20 16:23:015805TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085806 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5807}
5808
bncd16676a2016-07-20 16:23:015809TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085810 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5811}
5812
bncd16676a2016-07-20 16:23:015813TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085814 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5815}
5816
[email protected]038e9a32008-10-08 22:40:165817// Test the flow when both the proxy server AND origin server require
5818// authentication. Again, this uses basic auth for both since that is
5819// the simplest to mock.
bncd16676a2016-07-20 16:23:015820TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275821 HttpRequestInfo request;
5822 request.method = "GET";
bncce36dca22015-04-21 22:11:235823 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275824
[email protected]038e9a32008-10-08 22:40:165825 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035826 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075828
bnc691fda62016-08-12 00:43:165829 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:165830
[email protected]f9ee6b52008-11-08 06:46:235831 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235832 MockWrite(
5833 "GET http://www.example.org/ HTTP/1.1\r\n"
5834 "Host: www.example.org\r\n"
5835 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235836 };
5837
[email protected]038e9a32008-10-08 22:40:165838 MockRead data_reads1[] = {
5839 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5840 // Give a couple authenticate options (only the middle one is actually
5841 // supported).
[email protected]22927ad2009-09-21 19:56:195842 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165843 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5844 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5845 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5846 // Large content-length -- won't matter, as connection will be reset.
5847 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065848 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165849 };
5850
bnc691fda62016-08-12 00:43:165851 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:165852 // request we should be issuing -- the final header line contains the
5853 // proxy's credentials.
5854 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235855 MockWrite(
5856 "GET http://www.example.org/ HTTP/1.1\r\n"
5857 "Host: www.example.org\r\n"
5858 "Proxy-Connection: keep-alive\r\n"
5859 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165860 };
5861
5862 // Now the proxy server lets the request pass through to origin server.
5863 // The origin server responds with a 401.
5864 MockRead data_reads2[] = {
5865 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5866 // Note: We are using the same realm-name as the proxy server. This is
5867 // completely valid, as realms are unique across hosts.
5868 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5869 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5870 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065871 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165872 };
5873
bnc691fda62016-08-12 00:43:165874 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:165875 // the credentials for both the proxy and origin server.
5876 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235877 MockWrite(
5878 "GET http://www.example.org/ HTTP/1.1\r\n"
5879 "Host: www.example.org\r\n"
5880 "Proxy-Connection: keep-alive\r\n"
5881 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5882 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165883 };
5884
5885 // Lastly we get the desired content.
5886 MockRead data_reads3[] = {
5887 MockRead("HTTP/1.0 200 OK\r\n"),
5888 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5889 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065890 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165891 };
5892
[email protected]31a2bfe2010-02-09 08:03:395893 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5894 data_writes1, arraysize(data_writes1));
5895 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5896 data_writes2, arraysize(data_writes2));
5897 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5898 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5900 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5901 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165902
[email protected]49639fa2011-12-20 23:22:415903 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165904
tfarina42834112016-09-22 13:38:205905 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015906 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165907
5908 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015909 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165910
bnc691fda62016-08-12 00:43:165911 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525912 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045913 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165914
[email protected]49639fa2011-12-20 23:22:415915 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165916
bnc691fda62016-08-12 00:43:165917 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015918 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165919
5920 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015921 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165922
bnc691fda62016-08-12 00:43:165923 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525924 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045925 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165926
[email protected]49639fa2011-12-20 23:22:415927 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165928
bnc691fda62016-08-12 00:43:165929 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
5930 callback3.callback());
robpercival214763f2016-07-01 23:27:015931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:165932
5933 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:015934 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:165935
bnc691fda62016-08-12 00:43:165936 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525937 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165938 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165939}
[email protected]4ddaf2502008-10-23 18:26:195940
[email protected]ea9dc9a2009-09-05 00:43:325941// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5942// can't hook into its internals to cause it to generate predictable NTLM
5943// authorization headers.
5944#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295945// The NTLM authentication unit tests were generated by capturing the HTTP
5946// requests and responses using Fiddler 2 and inspecting the generated random
5947// bytes in the debugger.
5948
5949// Enter the correct password and authenticate successfully.
bncd16676a2016-07-20 16:23:015950TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425951 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245952 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:095953 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545954
5955 // Ensure load is not disrupted by flags which suppress behaviour specific
5956 // to other auth schemes.
5957 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245958
[email protected]cb9bf6ca2011-01-28 13:15:275959 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5960 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095961 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275962
[email protected]3f918782009-02-28 01:29:245963 MockWrite data_writes1[] = {
5964 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5965 "Host: 172.22.68.17\r\n"
5966 "Connection: keep-alive\r\n\r\n"),
5967 };
5968
5969 MockRead data_reads1[] = {
5970 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045971 // Negotiate and NTLM are often requested together. However, we only want
5972 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5973 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245974 MockRead("WWW-Authenticate: NTLM\r\n"),
5975 MockRead("Connection: close\r\n"),
5976 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365977 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245978 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:245979 };
5980
5981 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:165982 // After restarting with a null identity, this is the
5983 // request we should be issuing -- the final header line contains a Type
5984 // 1 message.
5985 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5986 "Host: 172.22.68.17\r\n"
5987 "Connection: keep-alive\r\n"
5988 "Authorization: NTLM "
5989 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245990
bnc691fda62016-08-12 00:43:165991 // After calling trans.RestartWithAuth(), we should send a Type 3 message
5992 // (the credentials for the origin server). The second request continues
5993 // on the same connection.
5994 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5995 "Host: 172.22.68.17\r\n"
5996 "Connection: keep-alive\r\n"
5997 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5998 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5999 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
6000 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
6001 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246002 };
6003
6004 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026005 // The origin server responds with a Type 2 message.
6006 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6007 MockRead("WWW-Authenticate: NTLM "
6008 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
6009 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6010 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6011 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6012 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6013 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6014 "BtAAAAAAA=\r\n"),
6015 MockRead("Content-Length: 42\r\n"),
6016 MockRead("Content-Type: text/html\r\n\r\n"),
6017 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246018
Bence Béky1e4ef192017-09-18 19:58:026019 // Lastly we get the desired content.
6020 MockRead("HTTP/1.1 200 OK\r\n"),
6021 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6022 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246023 };
6024
[email protected]31a2bfe2010-02-09 08:03:396025 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6026 data_writes1, arraysize(data_writes1));
6027 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6028 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076029 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6030 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246031
Bence Béky83eb3512017-09-05 12:56:096032 SSLSocketDataProvider ssl1(ASYNC, OK);
6033 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6034 SSLSocketDataProvider ssl2(ASYNC, OK);
6035 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6036
[email protected]49639fa2011-12-20 23:22:416037 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246038
bnc691fda62016-08-12 00:43:166039 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506040
tfarina42834112016-09-22 13:38:206041 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246043
6044 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016045 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246046
bnc691fda62016-08-12 00:43:166047 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226048
bnc691fda62016-08-12 00:43:166049 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526050 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046051 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246052
[email protected]49639fa2011-12-20 23:22:416053 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256054
bnc691fda62016-08-12 00:43:166055 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6056 callback2.callback());
robpercival214763f2016-07-01 23:27:016057 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256058
6059 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016060 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256061
bnc691fda62016-08-12 00:43:166062 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256063
bnc691fda62016-08-12 00:43:166064 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526065 ASSERT_TRUE(response);
6066 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256067
[email protected]49639fa2011-12-20 23:22:416068 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246069
bnc691fda62016-08-12 00:43:166070 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016071 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246072
[email protected]0757e7702009-03-27 04:00:226073 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016074 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246075
bnc691fda62016-08-12 00:43:166076 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526077 ASSERT_TRUE(response);
6078 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026079 EXPECT_EQ(14, response->headers->GetContentLength());
6080
6081 std::string response_data;
6082 rv = ReadTransaction(&trans, &response_data);
6083 EXPECT_THAT(rv, IsOk());
6084 EXPECT_EQ("Please Login\r\n", response_data);
6085
6086 EXPECT_TRUE(data1.AllReadDataConsumed());
6087 EXPECT_TRUE(data1.AllWriteDataConsumed());
6088 EXPECT_TRUE(data2.AllReadDataConsumed());
6089 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246090}
6091
[email protected]385a4672009-03-11 22:21:296092// Enter a wrong password, and then the correct one.
bncd16676a2016-07-20 16:23:016093TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:426094 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296095 request.method = "GET";
Bence Béky83eb3512017-09-05 12:56:096096 request.url = GURL("https://172.22.68.17/kids/login.aspx");
[email protected]385a4672009-03-11 22:21:296097
[email protected]cb9bf6ca2011-01-28 13:15:276098 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
6099 MockGetHostName);
danakj1fd259a02016-04-16 03:17:096100 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276101
[email protected]385a4672009-03-11 22:21:296102 MockWrite data_writes1[] = {
6103 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6104 "Host: 172.22.68.17\r\n"
6105 "Connection: keep-alive\r\n\r\n"),
6106 };
6107
6108 MockRead data_reads1[] = {
6109 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046110 // Negotiate and NTLM are often requested together. However, we only want
6111 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6112 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296113 MockRead("WWW-Authenticate: NTLM\r\n"),
6114 MockRead("Connection: close\r\n"),
6115 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366116 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296117 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296118 };
6119
6120 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166121 // After restarting with a null identity, this is the
6122 // request we should be issuing -- the final header line contains a Type
6123 // 1 message.
6124 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6125 "Host: 172.22.68.17\r\n"
6126 "Connection: keep-alive\r\n"
6127 "Authorization: NTLM "
6128 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296129
bnc691fda62016-08-12 00:43:166130 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6131 // (the credentials for the origin server). The second request continues
6132 // on the same connection.
6133 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6134 "Host: 172.22.68.17\r\n"
6135 "Connection: keep-alive\r\n"
6136 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6137 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6138 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
6139 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
6140 "4Ww7b7E=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296141 };
6142
6143 MockRead data_reads2[] = {
6144 // The origin server responds with a Type 2 message.
6145 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6146 MockRead("WWW-Authenticate: NTLM "
6147 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
6148 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6149 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6150 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6151 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6152 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6153 "BtAAAAAAA=\r\n"),
6154 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366155 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296156 MockRead("You are not authorized to view this page\r\n"),
6157
6158 // Wrong password.
6159 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:296160 MockRead("WWW-Authenticate: NTLM\r\n"),
6161 MockRead("Connection: close\r\n"),
6162 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366163 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296164 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296165 };
6166
6167 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166168 // After restarting with a null identity, this is the
6169 // request we should be issuing -- the final header line contains a Type
6170 // 1 message.
6171 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6172 "Host: 172.22.68.17\r\n"
6173 "Connection: keep-alive\r\n"
6174 "Authorization: NTLM "
6175 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296176
bnc691fda62016-08-12 00:43:166177 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6178 // (the credentials for the origin server). The second request continues
6179 // on the same connection.
6180 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6181 "Host: 172.22.68.17\r\n"
6182 "Connection: keep-alive\r\n"
6183 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6184 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6185 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6186 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6187 "+4MUm7c=\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296188 };
6189
6190 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026191 // The origin server responds with a Type 2 message.
6192 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6193 MockRead("WWW-Authenticate: NTLM "
6194 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6195 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6196 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6197 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6198 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6199 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6200 "BtAAAAAAA=\r\n"),
6201 MockRead("Content-Length: 42\r\n"),
6202 MockRead("Content-Type: text/html\r\n\r\n"),
6203 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296204
Bence Béky1e4ef192017-09-18 19:58:026205 // Lastly we get the desired content.
6206 MockRead("HTTP/1.1 200 OK\r\n"),
6207 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6208 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296209 };
6210
[email protected]31a2bfe2010-02-09 08:03:396211 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6212 data_writes1, arraysize(data_writes1));
6213 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6214 data_writes2, arraysize(data_writes2));
6215 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6216 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076217 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6218 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6219 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296220
Bence Béky83eb3512017-09-05 12:56:096221 SSLSocketDataProvider ssl1(ASYNC, OK);
6222 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6223 SSLSocketDataProvider ssl2(ASYNC, OK);
6224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6225 SSLSocketDataProvider ssl3(ASYNC, OK);
6226 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6227
[email protected]49639fa2011-12-20 23:22:416228 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296229
bnc691fda62016-08-12 00:43:166230 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506231
tfarina42834112016-09-22 13:38:206232 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296234
6235 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016236 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296237
bnc691fda62016-08-12 00:43:166238 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296239
bnc691fda62016-08-12 00:43:166240 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526241 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046242 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296243
[email protected]49639fa2011-12-20 23:22:416244 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296245
[email protected]0757e7702009-03-27 04:00:226246 // Enter the wrong password.
bnc691fda62016-08-12 00:43:166247 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
6248 callback2.callback());
robpercival214763f2016-07-01 23:27:016249 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296250
[email protected]10af5fe72011-01-31 16:17:256251 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016252 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296253
bnc691fda62016-08-12 00:43:166254 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416255 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166256 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016257 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256258 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016259 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166260 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226261
bnc691fda62016-08-12 00:43:166262 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526263 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046264 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226265
[email protected]49639fa2011-12-20 23:22:416266 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226267
6268 // Now enter the right password.
bnc691fda62016-08-12 00:43:166269 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6270 callback4.callback());
robpercival214763f2016-07-01 23:27:016271 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256272
6273 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016274 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256275
bnc691fda62016-08-12 00:43:166276 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256277
[email protected]49639fa2011-12-20 23:22:416278 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256279
6280 // One more roundtrip
bnc691fda62016-08-12 00:43:166281 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016282 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226283
6284 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016285 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226286
bnc691fda62016-08-12 00:43:166287 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526288 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026289 EXPECT_EQ(14, response->headers->GetContentLength());
6290
6291 std::string response_data;
6292 rv = ReadTransaction(&trans, &response_data);
6293 EXPECT_THAT(rv, IsOk());
6294 EXPECT_EQ("Please Login\r\n", response_data);
6295
6296 EXPECT_TRUE(data1.AllReadDataConsumed());
6297 EXPECT_TRUE(data1.AllWriteDataConsumed());
6298 EXPECT_TRUE(data2.AllReadDataConsumed());
6299 EXPECT_TRUE(data2.AllWriteDataConsumed());
6300 EXPECT_TRUE(data3.AllReadDataConsumed());
6301 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296302}
Bence Béky83eb3512017-09-05 12:56:096303
6304// NTLM is not supported over HTTP/2, therefore the server requests a downgrade,
6305// and the request is retried on an HTTP/1.1 connection.
6306TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
6307 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
6308 MockGetHostName);
6309
6310 const char* kUrl = "https://172.22.68.17/kids/login.aspx";
6311
6312 HttpRequestInfo request;
6313 request.method = "GET";
6314 request.url = GURL(kUrl);
6315
6316 // First request without credentials.
6317 SpdyHeaderBlock request_headers0(spdy_util_.ConstructGetHeaderBlock(kUrl));
6318 SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
6319 1, std::move(request_headers0), LOWEST, true));
6320
6321 SpdyHeaderBlock response_headers0;
6322 response_headers0[spdy_util_.GetStatusKey()] = "401";
6323 response_headers0["www-authenticate"] = "NTLM";
6324 SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
6325 1, std::move(response_headers0), true));
6326
6327 // Stream 1 is closed.
6328 spdy_util_.UpdateWithStreamDestruction(1);
6329
6330 // Retry with authorization header.
6331 SpdyHeaderBlock request_headers1(spdy_util_.ConstructGetHeaderBlock(kUrl));
6332 request_headers1["authorization"] =
6333 "NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=";
6334 SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
6335 3, std::move(request_headers1), LOWEST, true));
6336
6337 SpdySerializedFrame go_away(spdy_util_.ConstructSpdyGoAway(
6338 0, ERROR_CODE_HTTP_1_1_REQUIRED, "NTLM not supported over HTTP/2."));
6339
6340 MockWrite writes0[] = {
6341 CreateMockWrite(request0, 0), CreateMockWrite(request1, 2),
6342 };
6343 MockRead reads0[] = {CreateMockRead(resp, 1), CreateMockRead(go_away, 3)};
6344
6345 // Retry yet again using HTTP/1.1.
6346 MockWrite writes1[] = {
6347 // After restarting with a null identity, this is the
6348 // request we should be issuing -- the final header line contains a Type
6349 // 1 message.
6350 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6351 "Host: 172.22.68.17\r\n"
6352 "Connection: keep-alive\r\n"
6353 "Authorization: NTLM "
6354 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
6355
6356 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6357 // (the credentials for the origin server). The second request continues
6358 // on the same connection.
6359 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6360 "Host: 172.22.68.17\r\n"
6361 "Connection: keep-alive\r\n"
6362 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6363 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6364 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
6365 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
6366 "ahlhx5I=\r\n\r\n"),
6367 };
6368
6369 MockRead reads1[] = {
6370 // The origin server responds with a Type 2 message.
6371 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6372 MockRead("WWW-Authenticate: NTLM "
6373 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
6374 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6375 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6376 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6377 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6378 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6379 "BtAAAAAAA=\r\n"),
6380 MockRead("Content-Length: 42\r\n"),
6381 MockRead("Content-Type: text/html\r\n\r\n"),
6382 MockRead("You are not authorized to view this page\r\n"),
6383
6384 // Lastly we get the desired content.
6385 MockRead("HTTP/1.1 200 OK\r\n"),
6386 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026387 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096388 };
6389 SequencedSocketData data0(reads0, arraysize(reads0), writes0,
6390 arraysize(writes0));
6391 StaticSocketDataProvider data1(reads1, arraysize(reads1), writes1,
6392 arraysize(writes1));
6393 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6394 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6395
6396 SSLSocketDataProvider ssl0(ASYNC, OK);
6397 ssl0.next_proto = kProtoHTTP2;
6398 SSLSocketDataProvider ssl1(ASYNC, OK);
6399 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6400 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6401
6402 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6403 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6404
6405 TestCompletionCallback callback1;
6406 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6408
6409 rv = callback1.WaitForResult();
6410 EXPECT_THAT(rv, IsOk());
6411
6412 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6413
6414 const HttpResponseInfo* response = trans.GetResponseInfo();
6415 ASSERT_TRUE(response);
6416 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6417
6418 TestCompletionCallback callback2;
6419
6420 rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
6421 callback2.callback());
6422 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6423
6424 rv = callback2.WaitForResult();
6425 EXPECT_THAT(rv, IsOk());
6426
6427 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6428
6429 response = trans.GetResponseInfo();
6430 ASSERT_TRUE(response);
6431 EXPECT_FALSE(response->auth_challenge);
6432
6433 TestCompletionCallback callback3;
6434
6435 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6436 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6437
6438 rv = callback3.WaitForResult();
6439 EXPECT_THAT(rv, IsOk());
6440
6441 response = trans.GetResponseInfo();
6442 ASSERT_TRUE(response);
6443 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026444 EXPECT_EQ(14, response->headers->GetContentLength());
6445
6446 std::string response_data;
6447 rv = ReadTransaction(&trans, &response_data);
6448 EXPECT_THAT(rv, IsOk());
6449 EXPECT_EQ("Please Login\r\n", response_data);
6450
6451 EXPECT_TRUE(data0.AllReadDataConsumed());
6452 EXPECT_TRUE(data0.AllWriteDataConsumed());
6453 EXPECT_TRUE(data1.AllReadDataConsumed());
6454 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096455}
[email protected]ea9dc9a2009-09-05 00:43:326456#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296457
[email protected]4ddaf2502008-10-23 18:26:196458// Test reading a server response which has only headers, and no body.
6459// After some maximum number of bytes is consumed, the transaction should
6460// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016461TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426462 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196463 request.method = "GET";
bncce36dca22015-04-21 22:11:236464 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196465
danakj1fd259a02016-04-16 03:17:096466 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166467 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276468
[email protected]b75b7b2f2009-10-06 00:54:536469 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436470 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536471 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196472
6473 MockRead data_reads[] = {
6474 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066475 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196476 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066477 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196478 };
[email protected]31a2bfe2010-02-09 08:03:396479 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076480 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196481
[email protected]49639fa2011-12-20 23:22:416482 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196483
tfarina42834112016-09-22 13:38:206484 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:196486
6487 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016488 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:196489}
[email protected]f4e426b2008-11-05 00:24:496490
6491// Make sure that we don't try to reuse a TCPClientSocket when failing to
6492// establish tunnel.
6493// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:016494TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276495 HttpRequestInfo request;
6496 request.method = "GET";
bncce36dca22015-04-21 22:11:236497 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276498
[email protected]f4e426b2008-11-05 00:24:496499 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036500 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016501
danakj1fd259a02016-04-16 03:17:096502 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496503
bnc87dcefc2017-05-25 12:47:586504 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196505 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:496506
[email protected]f4e426b2008-11-05 00:24:496507 // Since we have proxy, should try to establish tunnel.
6508 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176509 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6510 "Host: www.example.org:443\r\n"
6511 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496512 };
6513
[email protected]77848d12008-11-14 00:00:226514 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496515 // connection. Usually a proxy would return 501 (not implemented),
6516 // or 200 (tunnel established).
6517 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236518 MockRead("HTTP/1.1 404 Not Found\r\n"),
6519 MockRead("Content-Length: 10\r\n\r\n"),
6520 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496521 };
6522
[email protected]31a2bfe2010-02-09 08:03:396523 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6524 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076525 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496526
[email protected]49639fa2011-12-20 23:22:416527 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496528
tfarina42834112016-09-22 13:38:206529 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016530 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:496531
6532 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016533 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:496534
[email protected]b4404c02009-04-10 16:38:526535 // Empty the current queue. This is necessary because idle sockets are
6536 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556537 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526538
[email protected]f4e426b2008-11-05 00:24:496539 // We now check to make sure the TCPClientSocket was not added back to
6540 // the pool.
[email protected]90499482013-06-01 00:39:506541 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496542 trans.reset();
fdoray92e35a72016-06-10 15:54:556543 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496544 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506545 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496546}
[email protected]372d34a2008-11-05 21:30:516547
[email protected]1b157c02009-04-21 01:55:406548// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:016549TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426550 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406551 request.method = "GET";
bncce36dca22015-04-21 22:11:236552 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406553
danakj1fd259a02016-04-16 03:17:096554 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276555
bnc691fda62016-08-12 00:43:166556 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:276557
[email protected]1b157c02009-04-21 01:55:406558 MockRead data_reads[] = {
6559 // A part of the response body is received with the response headers.
6560 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6561 // The rest of the response body is received in two parts.
6562 MockRead("lo"),
6563 MockRead(" world"),
6564 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066565 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406566 };
6567
[email protected]31a2bfe2010-02-09 08:03:396568 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076569 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406570
[email protected]49639fa2011-12-20 23:22:416571 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406572
tfarina42834112016-09-22 13:38:206573 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016574 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:406575
6576 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016577 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406578
bnc691fda62016-08-12 00:43:166579 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526580 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406581
wezca1070932016-05-26 20:30:526582 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406583 std::string status_line = response->headers->GetStatusLine();
6584 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6585
[email protected]90499482013-06-01 00:39:506586 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406587
6588 std::string response_data;
bnc691fda62016-08-12 00:43:166589 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016590 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:406591 EXPECT_EQ("hello world", response_data);
6592
6593 // Empty the current queue. This is necessary because idle sockets are
6594 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556595 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406596
6597 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506598 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406599}
6600
[email protected]76a505b2010-08-25 06:23:006601// Make sure that we recycle a SSL socket after reading all of the response
6602// body.
bncd16676a2016-07-20 16:23:016603TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006604 HttpRequestInfo request;
6605 request.method = "GET";
bncce36dca22015-04-21 22:11:236606 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006607
6608 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236609 MockWrite(
6610 "GET / HTTP/1.1\r\n"
6611 "Host: www.example.org\r\n"
6612 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006613 };
6614
6615 MockRead data_reads[] = {
6616 MockRead("HTTP/1.1 200 OK\r\n"),
6617 MockRead("Content-Length: 11\r\n\r\n"),
6618 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066619 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006620 };
6621
[email protected]8ddf8322012-02-23 18:08:066622 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006624
6625 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6626 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076627 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006628
[email protected]49639fa2011-12-20 23:22:416629 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006630
danakj1fd259a02016-04-16 03:17:096631 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166632 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006633
tfarina42834112016-09-22 13:38:206634 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006635
robpercival214763f2016-07-01 23:27:016636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6637 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006638
bnc691fda62016-08-12 00:43:166639 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526640 ASSERT_TRUE(response);
6641 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006642 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6643
[email protected]90499482013-06-01 00:39:506644 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006645
6646 std::string response_data;
bnc691fda62016-08-12 00:43:166647 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016648 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006649 EXPECT_EQ("hello world", response_data);
6650
6651 // Empty the current queue. This is necessary because idle sockets are
6652 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556653 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006654
6655 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506656 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006657}
6658
6659// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6660// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:016661TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006662 HttpRequestInfo request;
6663 request.method = "GET";
bncce36dca22015-04-21 22:11:236664 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006665
6666 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236667 MockWrite(
6668 "GET / HTTP/1.1\r\n"
6669 "Host: www.example.org\r\n"
6670 "Connection: keep-alive\r\n\r\n"),
6671 MockWrite(
6672 "GET / HTTP/1.1\r\n"
6673 "Host: www.example.org\r\n"
6674 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006675 };
6676
6677 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426678 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6679 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006680
[email protected]8ddf8322012-02-23 18:08:066681 SSLSocketDataProvider ssl(ASYNC, OK);
6682 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076683 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6684 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006685
6686 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6687 data_writes, arraysize(data_writes));
6688 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6689 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076690 session_deps_.socket_factory->AddSocketDataProvider(&data);
6691 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006692
[email protected]49639fa2011-12-20 23:22:416693 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006694
danakj1fd259a02016-04-16 03:17:096695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:586696 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196697 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006698
tfarina42834112016-09-22 13:38:206699 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006700
robpercival214763f2016-07-01 23:27:016701 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6702 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006703
6704 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526705 ASSERT_TRUE(response);
6706 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006707 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6708
[email protected]90499482013-06-01 00:39:506709 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006710
6711 std::string response_data;
6712 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016713 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006714 EXPECT_EQ("hello world", response_data);
6715
6716 // Empty the current queue. This is necessary because idle sockets are
6717 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556718 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006719
6720 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506721 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006722
6723 // Now start the second transaction, which should reuse the previous socket.
6724
bnc87dcefc2017-05-25 12:47:586725 trans =
Jeremy Roman0579ed62017-08-29 15:56:196726 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:006727
tfarina42834112016-09-22 13:38:206728 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:006729
robpercival214763f2016-07-01 23:27:016730 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6731 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:006732
6733 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526734 ASSERT_TRUE(response);
6735 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006736 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6737
[email protected]90499482013-06-01 00:39:506738 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006739
6740 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:016741 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:006742 EXPECT_EQ("hello world", response_data);
6743
6744 // Empty the current queue. This is necessary because idle sockets are
6745 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556746 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006747
6748 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506749 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006750}
6751
maksim.sisov0adf8592016-07-15 06:25:566752// Grab a socket, use it, and put it back into the pool. Then, make
6753// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016754TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566755 HttpRequestInfo request;
6756 request.method = "GET";
6757 request.url = GURL("http://www.example.org/");
6758 request.load_flags = 0;
6759
6760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6761
bnc691fda62016-08-12 00:43:166762 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566763
6764 MockRead data_reads[] = {
6765 // A part of the response body is received with the response headers.
6766 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6767 // The rest of the response body is received in two parts.
6768 MockRead("lo"), MockRead(" world"),
6769 MockRead("junk"), // Should not be read!!
6770 MockRead(SYNCHRONOUS, OK),
6771 };
6772
6773 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
6774 session_deps_.socket_factory->AddSocketDataProvider(&data);
6775
6776 TestCompletionCallback callback;
6777
tfarina42834112016-09-22 13:38:206778 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566779 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6780
6781 EXPECT_THAT(callback.GetResult(rv), IsOk());
6782
bnc691fda62016-08-12 00:43:166783 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566784 ASSERT_TRUE(response);
6785 EXPECT_TRUE(response->headers);
6786 std::string status_line = response->headers->GetStatusLine();
6787 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6788
6789 // Make memory critical notification and ensure the transaction still has been
6790 // operating right.
6791 base::MemoryPressureListener::NotifyMemoryPressure(
6792 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6793 base::RunLoop().RunUntilIdle();
6794
6795 // Socket should not be flushed as long as it is not idle.
6796 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6797
6798 std::string response_data;
bnc691fda62016-08-12 00:43:166799 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566800 EXPECT_THAT(rv, IsOk());
6801 EXPECT_EQ("hello world", response_data);
6802
6803 // Empty the current queue. This is necessary because idle sockets are
6804 // added to the connection pool asynchronously with a PostTask.
6805 base::RunLoop().RunUntilIdle();
6806
6807 // We now check to make sure the socket was added back to the pool.
6808 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
6809
6810 // Idle sockets should be flushed now.
6811 base::MemoryPressureListener::NotifyMemoryPressure(
6812 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6813 base::RunLoop().RunUntilIdle();
6814
6815 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
6816}
6817
6818// Grab an SSL socket, use it, and put it back into the pool. Then, make
6819// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:016820TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:566821 HttpRequestInfo request;
6822 request.method = "GET";
6823 request.url = GURL("https://www.example.org/");
6824 request.load_flags = 0;
6825
6826 MockWrite data_writes[] = {
6827 MockWrite("GET / HTTP/1.1\r\n"
6828 "Host: www.example.org\r\n"
6829 "Connection: keep-alive\r\n\r\n"),
6830 };
6831
6832 MockRead data_reads[] = {
6833 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6834 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
6835
6836 SSLSocketDataProvider ssl(ASYNC, OK);
6837 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6838
6839 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
6840 arraysize(data_writes));
6841 session_deps_.socket_factory->AddSocketDataProvider(&data);
6842
6843 TestCompletionCallback callback;
6844
6845 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:166846 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:566847
6848 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:206849 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:566850
6851 EXPECT_THAT(callback.GetResult(rv), IsOk());
6852
bnc691fda62016-08-12 00:43:166853 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:566854 ASSERT_TRUE(response);
6855 ASSERT_TRUE(response->headers);
6856 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6857
6858 // Make memory critical notification and ensure the transaction still has been
6859 // operating right.
6860 base::MemoryPressureListener::NotifyMemoryPressure(
6861 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6862 base::RunLoop().RunUntilIdle();
6863
6864 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6865
6866 std::string response_data;
bnc691fda62016-08-12 00:43:166867 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:566868 EXPECT_THAT(rv, IsOk());
6869 EXPECT_EQ("hello world", response_data);
6870
6871 // Empty the current queue. This is necessary because idle sockets are
6872 // added to the connection pool asynchronously with a PostTask.
6873 base::RunLoop().RunUntilIdle();
6874
6875 // We now check to make sure the socket was added back to the pool.
6876 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
6877
6878 // Make memory notification once again and ensure idle socket is closed.
6879 base::MemoryPressureListener::NotifyMemoryPressure(
6880 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
6881 base::RunLoop().RunUntilIdle();
6882
6883 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
6884}
6885
[email protected]b4404c02009-04-10 16:38:526886// Make sure that we recycle a socket after a zero-length response.
6887// http://crbug.com/9880
bncd16676a2016-07-20 16:23:016888TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426889 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526890 request.method = "GET";
bncce36dca22015-04-21 22:11:236891 request.url = GURL(
6892 "http://www.example.org/csi?v=3&s=web&action=&"
6893 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6894 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6895 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526896
danakj1fd259a02016-04-16 03:17:096897 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276898
[email protected]b4404c02009-04-10 16:38:526899 MockRead data_reads[] = {
6900 MockRead("HTTP/1.1 204 No Content\r\n"
6901 "Content-Length: 0\r\n"
6902 "Content-Type: text/html\r\n\r\n"),
6903 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066904 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526905 };
6906
[email protected]31a2bfe2010-02-09 08:03:396907 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076908 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526909
mmenkecc2298e2015-12-07 18:20:186910 // Transaction must be created after the MockReads, so it's destroyed before
6911 // them.
bnc691fda62016-08-12 00:43:166912 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:186913
[email protected]49639fa2011-12-20 23:22:416914 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526915
tfarina42834112016-09-22 13:38:206916 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016917 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:526918
6919 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016920 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526921
bnc691fda62016-08-12 00:43:166922 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526923 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526924
wezca1070932016-05-26 20:30:526925 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526926 std::string status_line = response->headers->GetStatusLine();
6927 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6928
[email protected]90499482013-06-01 00:39:506929 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526930
6931 std::string response_data;
bnc691fda62016-08-12 00:43:166932 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:016933 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:526934 EXPECT_EQ("", response_data);
6935
6936 // Empty the current queue. This is necessary because idle sockets are
6937 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556938 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526939
6940 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506941 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526942}
6943
bncd16676a2016-07-20 16:23:016944TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096945 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226946 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:196947 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:226948 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276949
[email protected]1c773ea12009-04-28 19:58:426950 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516951 // Transaction 1: a GET request that succeeds. The socket is recycled
6952 // after use.
6953 request[0].method = "GET";
6954 request[0].url = GURL("http://www.google.com/");
6955 request[0].load_flags = 0;
6956 // Transaction 2: a POST request. Reuses the socket kept alive from
6957 // transaction 1. The first attempts fails when writing the POST data.
6958 // This causes the transaction to retry with a new socket. The second
6959 // attempt succeeds.
6960 request[1].method = "POST";
6961 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276962 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516963 request[1].load_flags = 0;
6964
danakj1fd259a02016-04-16 03:17:096965 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516966
6967 // The first socket is used for transaction 1 and the first attempt of
6968 // transaction 2.
6969
6970 // The response of transaction 1.
6971 MockRead data_reads1[] = {
6972 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6973 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066974 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516975 };
6976 // The mock write results of transaction 1 and the first attempt of
6977 // transaction 2.
6978 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066979 MockWrite(SYNCHRONOUS, 64), // GET
6980 MockWrite(SYNCHRONOUS, 93), // POST
6981 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516982 };
[email protected]31a2bfe2010-02-09 08:03:396983 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6984 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516985
6986 // The second socket is used for the second attempt of transaction 2.
6987
6988 // The response of transaction 2.
6989 MockRead data_reads2[] = {
6990 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6991 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066992 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516993 };
6994 // The mock write results of the second attempt of transaction 2.
6995 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066996 MockWrite(SYNCHRONOUS, 93), // POST
6997 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516998 };
[email protected]31a2bfe2010-02-09 08:03:396999 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7000 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:517001
[email protected]bb88e1d32013-05-03 23:11:077002 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7003 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517004
thestig9d3bb0c2015-01-24 00:49:517005 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517006 "hello world", "welcome"
7007 };
7008
7009 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167010 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517011
[email protected]49639fa2011-12-20 23:22:417012 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517013
tfarina42834112016-09-22 13:38:207014 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517016
7017 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017018 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517019
bnc691fda62016-08-12 00:43:167020 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527021 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517022
wezca1070932016-05-26 20:30:527023 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517024 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7025
7026 std::string response_data;
bnc691fda62016-08-12 00:43:167027 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017028 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517029 EXPECT_EQ(kExpectedResponseData[i], response_data);
7030 }
7031}
[email protected]f9ee6b52008-11-08 06:46:237032
7033// Test the request-challenge-retry sequence for basic auth when there is
7034// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167035// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017036TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427037 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237038 request.method = "GET";
bncce36dca22015-04-21 22:11:237039 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417040 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:297041
danakj1fd259a02016-04-16 03:17:097042 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167043 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277044
[email protected]a97cca42009-08-14 01:00:297045 // The password contains an escaped character -- for this test to pass it
7046 // will need to be unescaped by HttpNetworkTransaction.
7047 EXPECT_EQ("b%40r", request.url.password());
7048
[email protected]f9ee6b52008-11-08 06:46:237049 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237050 MockWrite(
7051 "GET / HTTP/1.1\r\n"
7052 "Host: www.example.org\r\n"
7053 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237054 };
7055
7056 MockRead data_reads1[] = {
7057 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7058 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7059 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067060 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237061 };
7062
[email protected]2262e3a2012-05-22 16:08:167063 // After the challenge above, the transaction will be restarted using the
7064 // identity from the url (foo, b@r) to answer the challenge.
7065 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237066 MockWrite(
7067 "GET / HTTP/1.1\r\n"
7068 "Host: www.example.org\r\n"
7069 "Connection: keep-alive\r\n"
7070 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167071 };
7072
7073 MockRead data_reads2[] = {
7074 MockRead("HTTP/1.0 200 OK\r\n"),
7075 MockRead("Content-Length: 100\r\n\r\n"),
7076 MockRead(SYNCHRONOUS, OK),
7077 };
7078
[email protected]31a2bfe2010-02-09 08:03:397079 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7080 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:167081 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7082 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077083 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7084 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237085
[email protected]49639fa2011-12-20 23:22:417086 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207087 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237089 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017090 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167091 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167092
7093 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167094 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017095 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167096 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017097 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167098 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227099
bnc691fda62016-08-12 00:43:167100 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527101 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167102
7103 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527104 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167105
7106 EXPECT_EQ(100, response->headers->GetContentLength());
7107
7108 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557109 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167110}
7111
7112// Test the request-challenge-retry sequence for basic auth when there is an
7113// incorrect identity in the URL. The identity from the URL should be used only
7114// once.
bncd16676a2016-07-20 16:23:017115TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167116 HttpRequestInfo request;
7117 request.method = "GET";
7118 // Note: the URL has a username:password in it. The password "baz" is
7119 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237120 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167121
7122 request.load_flags = LOAD_NORMAL;
7123
danakj1fd259a02016-04-16 03:17:097124 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167125 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167126
7127 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237128 MockWrite(
7129 "GET / HTTP/1.1\r\n"
7130 "Host: www.example.org\r\n"
7131 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167132 };
7133
7134 MockRead data_reads1[] = {
7135 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7136 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7137 MockRead("Content-Length: 10\r\n\r\n"),
7138 MockRead(SYNCHRONOUS, ERR_FAILED),
7139 };
7140
7141 // After the challenge above, the transaction will be restarted using the
7142 // identity from the url (foo, baz) to answer the challenge.
7143 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237144 MockWrite(
7145 "GET / HTTP/1.1\r\n"
7146 "Host: www.example.org\r\n"
7147 "Connection: keep-alive\r\n"
7148 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167149 };
7150
7151 MockRead data_reads2[] = {
7152 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7153 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7154 MockRead("Content-Length: 10\r\n\r\n"),
7155 MockRead(SYNCHRONOUS, ERR_FAILED),
7156 };
7157
7158 // After the challenge above, the transaction will be restarted using the
7159 // identity supplied by the user (foo, bar) to answer the challenge.
7160 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237161 MockWrite(
7162 "GET / HTTP/1.1\r\n"
7163 "Host: www.example.org\r\n"
7164 "Connection: keep-alive\r\n"
7165 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167166 };
7167
7168 MockRead data_reads3[] = {
7169 MockRead("HTTP/1.0 200 OK\r\n"),
7170 MockRead("Content-Length: 100\r\n\r\n"),
7171 MockRead(SYNCHRONOUS, OK),
7172 };
7173
7174 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7175 data_writes1, arraysize(data_writes1));
7176 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7177 data_writes2, arraysize(data_writes2));
7178 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7179 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077180 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7181 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7182 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167183
7184 TestCompletionCallback callback1;
7185
tfarina42834112016-09-22 13:38:207186 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167188
7189 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017190 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167191
bnc691fda62016-08-12 00:43:167192 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167193 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167194 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017195 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167196 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017197 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167198 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167199
bnc691fda62016-08-12 00:43:167200 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527201 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167202 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7203
7204 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167205 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017206 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167207 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017208 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167209 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167210
bnc691fda62016-08-12 00:43:167211 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527212 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167213
7214 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527215 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167216
7217 EXPECT_EQ(100, response->headers->GetContentLength());
7218
[email protected]ea9dc9a2009-09-05 00:43:327219 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557220 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327221}
7222
[email protected]2217aa22013-10-11 03:03:547223
7224// Test the request-challenge-retry sequence for basic auth when there is a
7225// correct identity in the URL, but its use is being suppressed. The identity
7226// from the URL should never be used.
bncd16676a2016-07-20 16:23:017227TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547228 HttpRequestInfo request;
7229 request.method = "GET";
bncce36dca22015-04-21 22:11:237230 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547231 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7232
danakj1fd259a02016-04-16 03:17:097233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167234 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547235
7236 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237237 MockWrite(
7238 "GET / HTTP/1.1\r\n"
7239 "Host: www.example.org\r\n"
7240 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547241 };
7242
7243 MockRead data_reads1[] = {
7244 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7245 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7246 MockRead("Content-Length: 10\r\n\r\n"),
7247 MockRead(SYNCHRONOUS, ERR_FAILED),
7248 };
7249
7250 // After the challenge above, the transaction will be restarted using the
7251 // identity supplied by the user, not the one in the URL, to answer the
7252 // challenge.
7253 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237254 MockWrite(
7255 "GET / HTTP/1.1\r\n"
7256 "Host: www.example.org\r\n"
7257 "Connection: keep-alive\r\n"
7258 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547259 };
7260
7261 MockRead data_reads3[] = {
7262 MockRead("HTTP/1.0 200 OK\r\n"),
7263 MockRead("Content-Length: 100\r\n\r\n"),
7264 MockRead(SYNCHRONOUS, OK),
7265 };
7266
7267 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7268 data_writes1, arraysize(data_writes1));
7269 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7270 data_writes3, arraysize(data_writes3));
7271 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7272 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7273
7274 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207275 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017276 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547277 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017278 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167279 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547280
bnc691fda62016-08-12 00:43:167281 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527282 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547283 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7284
7285 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167286 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017287 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547288 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017289 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167290 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547291
bnc691fda62016-08-12 00:43:167292 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527293 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547294
7295 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527296 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547297 EXPECT_EQ(100, response->headers->GetContentLength());
7298
7299 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557300 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547301}
7302
[email protected]f9ee6b52008-11-08 06:46:237303// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017304TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097305 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237306
7307 // Transaction 1: authenticate (foo, bar) on MyRealm1
7308 {
[email protected]1c773ea12009-04-28 19:58:427309 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237310 request.method = "GET";
bncce36dca22015-04-21 22:11:237311 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:237312
bnc691fda62016-08-12 00:43:167313 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277314
[email protected]f9ee6b52008-11-08 06:46:237315 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237316 MockWrite(
7317 "GET /x/y/z HTTP/1.1\r\n"
7318 "Host: www.example.org\r\n"
7319 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237320 };
7321
7322 MockRead data_reads1[] = {
7323 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7324 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7325 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067326 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237327 };
7328
7329 // Resend with authorization (username=foo, password=bar)
7330 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237331 MockWrite(
7332 "GET /x/y/z HTTP/1.1\r\n"
7333 "Host: www.example.org\r\n"
7334 "Connection: keep-alive\r\n"
7335 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237336 };
7337
7338 // Sever accepts the authorization.
7339 MockRead data_reads2[] = {
7340 MockRead("HTTP/1.0 200 OK\r\n"),
7341 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067342 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237343 };
7344
[email protected]31a2bfe2010-02-09 08:03:397345 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7346 data_writes1, arraysize(data_writes1));
7347 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7348 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077349 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7350 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237351
[email protected]49639fa2011-12-20 23:22:417352 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237353
tfarina42834112016-09-22 13:38:207354 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017355 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237356
7357 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017358 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237359
bnc691fda62016-08-12 00:43:167360 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527361 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047362 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237363
[email protected]49639fa2011-12-20 23:22:417364 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237365
bnc691fda62016-08-12 00:43:167366 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7367 callback2.callback());
robpercival214763f2016-07-01 23:27:017368 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237369
7370 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017371 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237372
bnc691fda62016-08-12 00:43:167373 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527374 ASSERT_TRUE(response);
7375 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237376 EXPECT_EQ(100, response->headers->GetContentLength());
7377 }
7378
7379 // ------------------------------------------------------------------------
7380
7381 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
7382 {
[email protected]1c773ea12009-04-28 19:58:427383 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237384 request.method = "GET";
7385 // Note that Transaction 1 was at /x/y/z, so this is in the same
7386 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:237387 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:237388
bnc691fda62016-08-12 00:43:167389 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277390
[email protected]f9ee6b52008-11-08 06:46:237391 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237392 MockWrite(
7393 "GET /x/y/a/b HTTP/1.1\r\n"
7394 "Host: www.example.org\r\n"
7395 "Connection: keep-alive\r\n"
7396 // Send preemptive authorization for MyRealm1
7397 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237398 };
7399
7400 // The server didn't like the preemptive authorization, and
7401 // challenges us for a different realm (MyRealm2).
7402 MockRead data_reads1[] = {
7403 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7404 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
7405 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067406 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237407 };
7408
7409 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
7410 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237411 MockWrite(
7412 "GET /x/y/a/b HTTP/1.1\r\n"
7413 "Host: www.example.org\r\n"
7414 "Connection: keep-alive\r\n"
7415 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237416 };
7417
7418 // Sever accepts the authorization.
7419 MockRead data_reads2[] = {
7420 MockRead("HTTP/1.0 200 OK\r\n"),
7421 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067422 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237423 };
7424
[email protected]31a2bfe2010-02-09 08:03:397425 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7426 data_writes1, arraysize(data_writes1));
7427 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7428 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077429 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7430 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237431
[email protected]49639fa2011-12-20 23:22:417432 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237433
tfarina42834112016-09-22 13:38:207434 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017435 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237436
7437 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017438 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237439
bnc691fda62016-08-12 00:43:167440 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527441 ASSERT_TRUE(response);
7442 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:047443 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:437444 EXPECT_EQ("http://www.example.org",
7445 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:047446 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:197447 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:237448
[email protected]49639fa2011-12-20 23:22:417449 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237450
bnc691fda62016-08-12 00:43:167451 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7452 callback2.callback());
robpercival214763f2016-07-01 23:27:017453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237454
7455 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017456 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237457
bnc691fda62016-08-12 00:43:167458 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527459 ASSERT_TRUE(response);
7460 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237461 EXPECT_EQ(100, response->headers->GetContentLength());
7462 }
7463
7464 // ------------------------------------------------------------------------
7465
7466 // Transaction 3: Resend a request in MyRealm's protection space --
7467 // succeed with preemptive authorization.
7468 {
[email protected]1c773ea12009-04-28 19:58:427469 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237470 request.method = "GET";
bncce36dca22015-04-21 22:11:237471 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237472
bnc691fda62016-08-12 00:43:167473 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277474
[email protected]f9ee6b52008-11-08 06:46:237475 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237476 MockWrite(
7477 "GET /x/y/z2 HTTP/1.1\r\n"
7478 "Host: www.example.org\r\n"
7479 "Connection: keep-alive\r\n"
7480 // The authorization for MyRealm1 gets sent preemptively
7481 // (since the url is in the same protection space)
7482 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237483 };
7484
7485 // Sever accepts the preemptive authorization
7486 MockRead data_reads1[] = {
7487 MockRead("HTTP/1.0 200 OK\r\n"),
7488 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067489 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237490 };
7491
[email protected]31a2bfe2010-02-09 08:03:397492 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7493 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077494 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237495
[email protected]49639fa2011-12-20 23:22:417496 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237497
tfarina42834112016-09-22 13:38:207498 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017499 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237500
7501 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017502 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237503
bnc691fda62016-08-12 00:43:167504 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527505 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237506
wezca1070932016-05-26 20:30:527507 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237508 EXPECT_EQ(100, response->headers->GetContentLength());
7509 }
7510
7511 // ------------------------------------------------------------------------
7512
7513 // Transaction 4: request another URL in MyRealm (however the
7514 // url is not known to belong to the protection space, so no pre-auth).
7515 {
[email protected]1c773ea12009-04-28 19:58:427516 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237517 request.method = "GET";
bncce36dca22015-04-21 22:11:237518 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237519
bnc691fda62016-08-12 00:43:167520 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277521
[email protected]f9ee6b52008-11-08 06:46:237522 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237523 MockWrite(
7524 "GET /x/1 HTTP/1.1\r\n"
7525 "Host: www.example.org\r\n"
7526 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237527 };
7528
7529 MockRead data_reads1[] = {
7530 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7531 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7532 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067533 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237534 };
7535
7536 // Resend with authorization from MyRealm's cache.
7537 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237538 MockWrite(
7539 "GET /x/1 HTTP/1.1\r\n"
7540 "Host: www.example.org\r\n"
7541 "Connection: keep-alive\r\n"
7542 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237543 };
7544
7545 // Sever accepts the authorization.
7546 MockRead data_reads2[] = {
7547 MockRead("HTTP/1.0 200 OK\r\n"),
7548 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067549 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237550 };
7551
[email protected]31a2bfe2010-02-09 08:03:397552 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7553 data_writes1, arraysize(data_writes1));
7554 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7555 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077556 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7557 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237558
[email protected]49639fa2011-12-20 23:22:417559 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237560
tfarina42834112016-09-22 13:38:207561 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017562 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237563
7564 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017565 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237566
bnc691fda62016-08-12 00:43:167567 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417568 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167569 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017570 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227571 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017572 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167573 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227574
bnc691fda62016-08-12 00:43:167575 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527576 ASSERT_TRUE(response);
7577 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237578 EXPECT_EQ(100, response->headers->GetContentLength());
7579 }
7580
7581 // ------------------------------------------------------------------------
7582
7583 // Transaction 5: request a URL in MyRealm, but the server rejects the
7584 // cached identity. Should invalidate and re-prompt.
7585 {
[email protected]1c773ea12009-04-28 19:58:427586 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237587 request.method = "GET";
bncce36dca22015-04-21 22:11:237588 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237589
bnc691fda62016-08-12 00:43:167590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277591
[email protected]f9ee6b52008-11-08 06:46:237592 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237593 MockWrite(
7594 "GET /p/q/t HTTP/1.1\r\n"
7595 "Host: www.example.org\r\n"
7596 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237597 };
7598
7599 MockRead data_reads1[] = {
7600 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7601 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7602 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067603 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237604 };
7605
7606 // Resend with authorization from cache for MyRealm.
7607 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237608 MockWrite(
7609 "GET /p/q/t HTTP/1.1\r\n"
7610 "Host: www.example.org\r\n"
7611 "Connection: keep-alive\r\n"
7612 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237613 };
7614
7615 // Sever rejects the authorization.
7616 MockRead data_reads2[] = {
7617 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7618 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7619 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067620 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237621 };
7622
7623 // At this point we should prompt for new credentials for MyRealm.
7624 // Restart with username=foo3, password=foo4.
7625 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237626 MockWrite(
7627 "GET /p/q/t HTTP/1.1\r\n"
7628 "Host: www.example.org\r\n"
7629 "Connection: keep-alive\r\n"
7630 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237631 };
7632
7633 // Sever accepts the authorization.
7634 MockRead data_reads3[] = {
7635 MockRead("HTTP/1.0 200 OK\r\n"),
7636 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067637 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237638 };
7639
[email protected]31a2bfe2010-02-09 08:03:397640 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7641 data_writes1, arraysize(data_writes1));
7642 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7643 data_writes2, arraysize(data_writes2));
7644 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7645 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077646 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7647 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7648 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237649
[email protected]49639fa2011-12-20 23:22:417650 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237651
tfarina42834112016-09-22 13:38:207652 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017653 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237654
7655 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017656 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237657
bnc691fda62016-08-12 00:43:167658 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417659 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167660 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017661 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227662 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017663 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167664 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227665
bnc691fda62016-08-12 00:43:167666 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527667 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047668 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237669
[email protected]49639fa2011-12-20 23:22:417670 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237671
bnc691fda62016-08-12 00:43:167672 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
7673 callback3.callback());
robpercival214763f2016-07-01 23:27:017674 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237675
[email protected]0757e7702009-03-27 04:00:227676 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017677 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237678
bnc691fda62016-08-12 00:43:167679 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527680 ASSERT_TRUE(response);
7681 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237682 EXPECT_EQ(100, response->headers->GetContentLength());
7683 }
7684}
[email protected]89ceba9a2009-03-21 03:46:067685
[email protected]3c32c5f2010-05-18 15:18:127686// Tests that nonce count increments when multiple auth attempts
7687// are started with the same nonce.
bncd16676a2016-07-20 16:23:017688TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447689 HttpAuthHandlerDigest::Factory* digest_factory =
7690 new HttpAuthHandlerDigest::Factory();
7691 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7692 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7693 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077694 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127696
7697 // Transaction 1: authenticate (foo, bar) on MyRealm1
7698 {
[email protected]3c32c5f2010-05-18 15:18:127699 HttpRequestInfo request;
7700 request.method = "GET";
bncce36dca22015-04-21 22:11:237701 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127702
bnc691fda62016-08-12 00:43:167703 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277704
[email protected]3c32c5f2010-05-18 15:18:127705 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237706 MockWrite(
7707 "GET /x/y/z HTTP/1.1\r\n"
7708 "Host: www.example.org\r\n"
7709 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127710 };
7711
7712 MockRead data_reads1[] = {
7713 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7714 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7715 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067716 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127717 };
7718
7719 // Resend with authorization (username=foo, password=bar)
7720 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237721 MockWrite(
7722 "GET /x/y/z HTTP/1.1\r\n"
7723 "Host: www.example.org\r\n"
7724 "Connection: keep-alive\r\n"
7725 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7726 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7727 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7728 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127729 };
7730
7731 // Sever accepts the authorization.
7732 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087733 MockRead("HTTP/1.0 200 OK\r\n"),
7734 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127735 };
7736
7737 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7738 data_writes1, arraysize(data_writes1));
7739 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7740 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077741 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7742 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127743
[email protected]49639fa2011-12-20 23:22:417744 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127745
tfarina42834112016-09-22 13:38:207746 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017747 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127748
7749 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017750 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127751
bnc691fda62016-08-12 00:43:167752 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527753 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047754 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127755
[email protected]49639fa2011-12-20 23:22:417756 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127757
bnc691fda62016-08-12 00:43:167758 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7759 callback2.callback());
robpercival214763f2016-07-01 23:27:017760 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127761
7762 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017763 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127764
bnc691fda62016-08-12 00:43:167765 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527766 ASSERT_TRUE(response);
7767 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127768 }
7769
7770 // ------------------------------------------------------------------------
7771
7772 // Transaction 2: Request another resource in digestive's protection space.
7773 // This will preemptively add an Authorization header which should have an
7774 // "nc" value of 2 (as compared to 1 in the first use.
7775 {
[email protected]3c32c5f2010-05-18 15:18:127776 HttpRequestInfo request;
7777 request.method = "GET";
7778 // Note that Transaction 1 was at /x/y/z, so this is in the same
7779 // protection space as digest.
bncce36dca22015-04-21 22:11:237780 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127781
bnc691fda62016-08-12 00:43:167782 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277783
[email protected]3c32c5f2010-05-18 15:18:127784 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237785 MockWrite(
7786 "GET /x/y/a/b HTTP/1.1\r\n"
7787 "Host: www.example.org\r\n"
7788 "Connection: keep-alive\r\n"
7789 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7790 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7791 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7792 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127793 };
7794
7795 // Sever accepts the authorization.
7796 MockRead data_reads1[] = {
7797 MockRead("HTTP/1.0 200 OK\r\n"),
7798 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067799 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127800 };
7801
7802 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7803 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077804 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127805
[email protected]49639fa2011-12-20 23:22:417806 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127807
tfarina42834112016-09-22 13:38:207808 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017809 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:127810
7811 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017812 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:127813
bnc691fda62016-08-12 00:43:167814 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527815 ASSERT_TRUE(response);
7816 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127817 }
7818}
7819
[email protected]89ceba9a2009-03-21 03:46:067820// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:017821TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067822 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097823 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167824 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:067825
7826 // Setup some state (which we expect ResetStateForRestart() will clear).
bnc691fda62016-08-12 00:43:167827 trans.read_buf_ = new IOBuffer(15);
7828 trans.read_buf_len_ = 15;
7829 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067830
7831 // Setup state in response_
bnc691fda62016-08-12 00:43:167832 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:577833 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087834 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577835 response->response_time = base::Time::Now();
7836 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067837
7838 { // Setup state for response_.vary_data
7839 HttpRequestInfo request;
7840 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7841 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277842 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437843 request.extra_headers.SetHeader("Foo", "1");
7844 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507845 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067846 }
7847
7848 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:167849 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:067850
7851 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:167852 EXPECT_FALSE(trans.read_buf_);
7853 EXPECT_EQ(0, trans.read_buf_len_);
7854 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527855 EXPECT_FALSE(response->auth_challenge);
7856 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047857 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087858 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577859 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067860}
7861
[email protected]bacff652009-03-31 17:50:337862// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:017863TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337864 HttpRequestInfo request;
7865 request.method = "GET";
bncce36dca22015-04-21 22:11:237866 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337867
danakj1fd259a02016-04-16 03:17:097868 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167869 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277870
[email protected]bacff652009-03-31 17:50:337871 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237872 MockWrite(
7873 "GET / HTTP/1.1\r\n"
7874 "Host: www.example.org\r\n"
7875 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337876 };
7877
7878 MockRead data_reads[] = {
7879 MockRead("HTTP/1.0 200 OK\r\n"),
7880 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7881 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067882 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337883 };
7884
[email protected]5ecc992a42009-11-11 01:41:597885 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397886 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7887 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067888 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7889 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337890
[email protected]bb88e1d32013-05-03 23:11:077891 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7892 session_deps_.socket_factory->AddSocketDataProvider(&data);
7893 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7894 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337895
[email protected]49639fa2011-12-20 23:22:417896 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337897
tfarina42834112016-09-22 13:38:207898 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017899 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337900
7901 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017902 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337903
bnc691fda62016-08-12 00:43:167904 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017905 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337906
7907 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017908 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337909
bnc691fda62016-08-12 00:43:167910 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337911
wezca1070932016-05-26 20:30:527912 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337913 EXPECT_EQ(100, response->headers->GetContentLength());
7914}
7915
7916// Test HTTPS connections to a site with a bad certificate, going through a
7917// proxy
bncd16676a2016-07-20 16:23:017918TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037919 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337920
7921 HttpRequestInfo request;
7922 request.method = "GET";
bncce36dca22015-04-21 22:11:237923 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337924
7925 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177926 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7927 "Host: www.example.org:443\r\n"
7928 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337929 };
7930
7931 MockRead proxy_reads[] = {
7932 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067933 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337934 };
7935
7936 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177937 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7938 "Host: www.example.org:443\r\n"
7939 "Proxy-Connection: keep-alive\r\n\r\n"),
7940 MockWrite("GET / HTTP/1.1\r\n"
7941 "Host: www.example.org\r\n"
7942 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337943 };
7944
7945 MockRead data_reads[] = {
7946 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7947 MockRead("HTTP/1.0 200 OK\r\n"),
7948 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7949 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067950 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337951 };
7952
[email protected]31a2bfe2010-02-09 08:03:397953 StaticSocketDataProvider ssl_bad_certificate(
7954 proxy_reads, arraysize(proxy_reads),
7955 proxy_writes, arraysize(proxy_writes));
7956 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7957 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067958 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7959 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337960
[email protected]bb88e1d32013-05-03 23:11:077961 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7962 session_deps_.socket_factory->AddSocketDataProvider(&data);
7963 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7964 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337965
[email protected]49639fa2011-12-20 23:22:417966 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337967
7968 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077969 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337970
danakj1fd259a02016-04-16 03:17:097971 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167972 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:337973
tfarina42834112016-09-22 13:38:207974 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017975 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337976
7977 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017978 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:337979
bnc691fda62016-08-12 00:43:167980 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:017981 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:337982
7983 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017984 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:337985
bnc691fda62016-08-12 00:43:167986 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:337987
wezca1070932016-05-26 20:30:527988 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337989 EXPECT_EQ(100, response->headers->GetContentLength());
7990 }
7991}
7992
[email protected]2df19bb2010-08-25 20:13:467993
7994// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:017995TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037996 session_deps_.proxy_service =
7997 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517998 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077999 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468000
8001 HttpRequestInfo request;
8002 request.method = "GET";
bncce36dca22015-04-21 22:11:238003 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468004
8005 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178006 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8007 "Host: www.example.org:443\r\n"
8008 "Proxy-Connection: keep-alive\r\n\r\n"),
8009 MockWrite("GET / HTTP/1.1\r\n"
8010 "Host: www.example.org\r\n"
8011 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468012 };
8013
8014 MockRead data_reads[] = {
8015 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8016 MockRead("HTTP/1.1 200 OK\r\n"),
8017 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8018 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068019 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468020 };
8021
8022 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8023 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068024 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8025 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468026
[email protected]bb88e1d32013-05-03 23:11:078027 session_deps_.socket_factory->AddSocketDataProvider(&data);
8028 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8029 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468030
[email protected]49639fa2011-12-20 23:22:418031 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468032
danakj1fd259a02016-04-16 03:17:098033 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468035
tfarina42834112016-09-22 13:38:208036 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018037 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468038
8039 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018040 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168041 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468042
wezca1070932016-05-26 20:30:528043 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468044
tbansal2ecbbc72016-10-06 17:15:478045 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468046 EXPECT_TRUE(response->headers->IsKeepAlive());
8047 EXPECT_EQ(200, response->headers->response_code());
8048 EXPECT_EQ(100, response->headers->GetContentLength());
8049 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208050
8051 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168052 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208053 TestLoadTimingNotReusedWithPac(load_timing_info,
8054 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468055}
8056
[email protected]511f6f52010-12-17 03:58:298057// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018058TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038059 session_deps_.proxy_service =
8060 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:518061 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078062 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298063
8064 HttpRequestInfo request;
8065 request.method = "GET";
bncce36dca22015-04-21 22:11:238066 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298067
8068 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178069 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8070 "Host: www.example.org:443\r\n"
8071 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298072 };
8073
8074 MockRead data_reads[] = {
8075 MockRead("HTTP/1.1 302 Redirect\r\n"),
8076 MockRead("Location: http://login.example.com/\r\n"),
8077 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068078 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298079 };
8080
8081 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8082 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068083 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298084
[email protected]bb88e1d32013-05-03 23:11:078085 session_deps_.socket_factory->AddSocketDataProvider(&data);
8086 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298087
[email protected]49639fa2011-12-20 23:22:418088 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298089
danakj1fd259a02016-04-16 03:17:098090 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168091 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298092
tfarina42834112016-09-22 13:38:208093 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018094 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298095
8096 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018097 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168098 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298099
wezca1070932016-05-26 20:30:528100 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298101
8102 EXPECT_EQ(302, response->headers->response_code());
8103 std::string url;
8104 EXPECT_TRUE(response->headers->IsRedirect(&url));
8105 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208106
8107 // In the case of redirects from proxies, HttpNetworkTransaction returns
8108 // timing for the proxy connection instead of the connection to the host,
8109 // and no send / receive times.
8110 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8111 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168112 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208113
8114 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198115 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208116
8117 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8118 EXPECT_LE(load_timing_info.proxy_resolve_start,
8119 load_timing_info.proxy_resolve_end);
8120 EXPECT_LE(load_timing_info.proxy_resolve_end,
8121 load_timing_info.connect_timing.connect_start);
8122 ExpectConnectTimingHasTimes(
8123 load_timing_info.connect_timing,
8124 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8125
8126 EXPECT_TRUE(load_timing_info.send_start.is_null());
8127 EXPECT_TRUE(load_timing_info.send_end.is_null());
8128 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298129}
8130
8131// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018132TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038133 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298134
8135 HttpRequestInfo request;
8136 request.method = "GET";
bncce36dca22015-04-21 22:11:238137 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298138
bncdf80d44fd2016-07-15 20:27:418139 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238140 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418141 SpdySerializedFrame goaway(
diannahu9904e272017-02-03 14:40:088142 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298143 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418144 CreateMockWrite(conn, 0, SYNCHRONOUS),
8145 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298146 };
8147
8148 static const char* const kExtraHeaders[] = {
8149 "location",
8150 "http://login.example.com/",
8151 };
bnc42331402016-07-25 13:36:158152 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238153 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298154 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418155 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298156 };
8157
rch8e6c6c42015-05-01 14:05:138158 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8159 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068160 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368161 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298162
[email protected]bb88e1d32013-05-03 23:11:078163 session_deps_.socket_factory->AddSocketDataProvider(&data);
8164 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298165
[email protected]49639fa2011-12-20 23:22:418166 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298167
danakj1fd259a02016-04-16 03:17:098168 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168169 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298170
tfarina42834112016-09-22 13:38:208171 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018172 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298173
8174 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018175 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168176 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298177
wezca1070932016-05-26 20:30:528178 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298179
8180 EXPECT_EQ(302, response->headers->response_code());
8181 std::string url;
8182 EXPECT_TRUE(response->headers->IsRedirect(&url));
8183 EXPECT_EQ("http://login.example.com/", url);
8184}
8185
[email protected]4eddbc732012-08-09 05:40:178186// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018187TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038188 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298189
8190 HttpRequestInfo request;
8191 request.method = "GET";
bncce36dca22015-04-21 22:11:238192 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298193
8194 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178195 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8196 "Host: www.example.org:443\r\n"
8197 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298198 };
8199
8200 MockRead data_reads[] = {
8201 MockRead("HTTP/1.1 404 Not Found\r\n"),
8202 MockRead("Content-Length: 23\r\n\r\n"),
8203 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068204 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298205 };
8206
8207 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8208 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068209 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298210
[email protected]bb88e1d32013-05-03 23:11:078211 session_deps_.socket_factory->AddSocketDataProvider(&data);
8212 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298213
[email protected]49639fa2011-12-20 23:22:418214 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298215
danakj1fd259a02016-04-16 03:17:098216 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168217 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298218
tfarina42834112016-09-22 13:38:208219 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018220 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298221
8222 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018223 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298224
ttuttle960fcbf2016-04-19 13:26:328225 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298226}
8227
[email protected]4eddbc732012-08-09 05:40:178228// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018229TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:038230 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:298231
8232 HttpRequestInfo request;
8233 request.method = "GET";
bncce36dca22015-04-21 22:11:238234 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:298235
bncdf80d44fd2016-07-15 20:27:418236 SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238237 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418238 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088239 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298240 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418241 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298242 };
8243
8244 static const char* const kExtraHeaders[] = {
8245 "location",
8246 "http://login.example.com/",
8247 };
bnc42331402016-07-25 13:36:158248 SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238249 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
bncdf80d44fd2016-07-15 20:27:418250 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(
bncb03b1092016-04-06 11:19:558251 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:298252 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418253 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138254 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298255 };
8256
rch8e6c6c42015-05-01 14:05:138257 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
8258 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:068259 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368260 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298261
[email protected]bb88e1d32013-05-03 23:11:078262 session_deps_.socket_factory->AddSocketDataProvider(&data);
8263 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298264
[email protected]49639fa2011-12-20 23:22:418265 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298266
danakj1fd259a02016-04-16 03:17:098267 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168268 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298269
tfarina42834112016-09-22 13:38:208270 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018271 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298272
8273 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018274 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298275
ttuttle960fcbf2016-04-19 13:26:328276 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298277}
8278
[email protected]0c5fb722012-02-28 11:50:358279// Test the request-challenge-retry sequence for basic auth, through
8280// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018281TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358282 HttpRequestInfo request;
8283 request.method = "GET";
bncce36dca22015-04-21 22:11:238284 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358285 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298286 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:358287
8288 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:038289 session_deps_.proxy_service =
8290 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:518291 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078292 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098293 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358294
8295 // Since we have proxy, should try to establish tunnel.
bncdf80d44fd2016-07-15 20:27:418296 SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238297 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncdf80d44fd2016-07-15 20:27:418298 SpdySerializedFrame rst(
diannahu9904e272017-02-03 14:40:088299 spdy_util_.ConstructSpdyRstStream(1, ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388300 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358301
bnc691fda62016-08-12 00:43:168302 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358303 // be issuing -- the final header line contains the credentials.
8304 const char* const kAuthCredentials[] = {
8305 "proxy-authorization", "Basic Zm9vOmJhcg==",
8306 };
bncdf80d44fd2016-07-15 20:27:418307 SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348308 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238309 HostPortPair("www.example.org", 443)));
8310 // fetch https://www.example.org/ via HTTP
8311 const char get[] =
8312 "GET / HTTP/1.1\r\n"
8313 "Host: www.example.org\r\n"
8314 "Connection: keep-alive\r\n\r\n";
bncdf80d44fd2016-07-15 20:27:418315 SpdySerializedFrame wrapped_get(
8316 spdy_util_.ConstructSpdyDataFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:358317
8318 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418319 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8320 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358321 };
8322
8323 // The proxy responds to the connect with a 407, using a persistent
8324 // connection.
thestig9d3bb0c2015-01-24 00:49:518325 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358326 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358327 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8328 };
bnc42331402016-07-25 13:36:158329 SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418330 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358331
bnc42331402016-07-25 13:36:158332 SpdySerializedFrame conn_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358333 const char resp[] = "HTTP/1.1 200 OK\r\n"
8334 "Content-Length: 5\r\n\r\n";
8335
bncdf80d44fd2016-07-15 20:27:418336 SpdySerializedFrame wrapped_get_resp(
8337 spdy_util_.ConstructSpdyDataFrame(3, resp, strlen(resp), false));
8338 SpdySerializedFrame wrapped_body(
8339 spdy_util_.ConstructSpdyDataFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:358340 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418341 CreateMockRead(conn_auth_resp, 1, ASYNC),
8342 CreateMockRead(conn_resp, 4, ASYNC),
8343 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8344 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138345 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358346 };
8347
rch8e6c6c42015-05-01 14:05:138348 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8349 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078350 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358351 // Negotiate SPDY to the proxy
8352 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368353 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078354 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358355 // Vanilla SSL to the server
8356 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078357 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358358
8359 TestCompletionCallback callback1;
8360
bnc87dcefc2017-05-25 12:47:588361 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198362 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:358363
8364 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018365 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358366
8367 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018368 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:468369 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:358370 log.GetEntries(&entries);
8371 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:008372 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
8373 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358374 ExpectLogContainsSomewhere(
8375 entries, pos,
mikecirone8b85c432016-09-08 19:11:008376 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
8377 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:358378
8379 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528380 ASSERT_TRUE(response);
8381 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:358382 EXPECT_EQ(407, response->headers->response_code());
8383 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:528384 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:438385 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:358386
8387 TestCompletionCallback callback2;
8388
8389 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
8390 callback2.callback());
robpercival214763f2016-07-01 23:27:018391 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:358392
8393 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018394 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:358395
8396 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528397 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:358398
8399 EXPECT_TRUE(response->headers->IsKeepAlive());
8400 EXPECT_EQ(200, response->headers->response_code());
8401 EXPECT_EQ(5, response->headers->GetContentLength());
8402 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8403
8404 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:528405 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:358406
[email protected]029c83b62013-01-24 05:28:208407 LoadTimingInfo load_timing_info;
8408 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8409 TestLoadTimingNotReusedWithPac(load_timing_info,
8410 CONNECT_TIMING_HAS_SSL_TIMES);
8411
[email protected]0c5fb722012-02-28 11:50:358412 trans.reset();
8413 session->CloseAllConnections();
8414}
8415
[email protected]7c6f7ba2012-04-03 04:09:298416// Test that an explicitly trusted SPDY proxy can push a resource from an
8417// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:018418TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:158419 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198420 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158421 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8422 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:298423 HttpRequestInfo request;
8424 HttpRequestInfo push_request;
8425
[email protected]7c6f7ba2012-04-03 04:09:298426 request.method = "GET";
bncce36dca22015-04-21 22:11:238427 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298428 push_request.method = "GET";
8429 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8430
tbansal28e68f82016-02-04 02:56:158431 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038432 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158433 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518434 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078435 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508436
inlinechan894515af2016-12-09 02:40:108437 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508438
danakj1fd259a02016-04-16 03:17:098439 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298440
bncdf80d44fd2016-07-15 20:27:418441 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458442 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358443 SpdySerializedFrame stream2_priority(
8444 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:298445
8446 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418447 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358448 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298449 };
8450
bncdf80d44fd2016-07-15 20:27:418451 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158452 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298453
bncdf80d44fd2016-07-15 20:27:418454 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298455
bncdf80d44fd2016-07-15 20:27:418456 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558457 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438458 const char kPushedData[] = "pushed";
bncdf80d44fd2016-07-15 20:27:418459 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(
8460 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:298461
8462 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418463 CreateMockRead(stream1_reply, 1, ASYNC),
8464 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358465 CreateMockRead(stream1_body, 4, ASYNC),
8466 CreateMockRead(stream2_body, 5, ASYNC),
8467 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298468 };
8469
rch8e6c6c42015-05-01 14:05:138470 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8471 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078472 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298473 // Negotiate SPDY to the proxy
8474 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368475 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078476 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298477
bnc87dcefc2017-05-25 12:47:588478 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198479 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:298480 TestCompletionCallback callback;
8481 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018482 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298483
8484 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018485 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298486 const HttpResponseInfo* response = trans->GetResponseInfo();
8487
bnc87dcefc2017-05-25 12:47:588488 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:198489 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:508490 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018491 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:298492
8493 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018494 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298495 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8496
wezca1070932016-05-26 20:30:528497 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298498 EXPECT_TRUE(response->headers->IsKeepAlive());
8499
8500 EXPECT_EQ(200, response->headers->response_code());
8501 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8502
8503 std::string response_data;
8504 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018505 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298506 EXPECT_EQ("hello!", response_data);
8507
[email protected]029c83b62013-01-24 05:28:208508 LoadTimingInfo load_timing_info;
8509 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8510 TestLoadTimingNotReusedWithPac(load_timing_info,
8511 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8512
[email protected]7c6f7ba2012-04-03 04:09:298513 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528514 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298515 EXPECT_EQ(200, push_response->headers->response_code());
8516
8517 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018518 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:298519 EXPECT_EQ("pushed", response_data);
8520
[email protected]029c83b62013-01-24 05:28:208521 LoadTimingInfo push_load_timing_info;
8522 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8523 TestLoadTimingReusedWithPac(push_load_timing_info);
8524 // The transactions should share a socket ID, despite being for different
8525 // origins.
8526 EXPECT_EQ(load_timing_info.socket_log_id,
8527 push_load_timing_info.socket_log_id);
8528
[email protected]7c6f7ba2012-04-03 04:09:298529 trans.reset();
8530 push_trans.reset();
8531 session->CloseAllConnections();
8532}
8533
[email protected]8c843192012-04-05 07:15:008534// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:018535TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158536 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198537 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158538 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8539 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008540 HttpRequestInfo request;
8541
8542 request.method = "GET";
bncce36dca22015-04-21 22:11:238543 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008544
tbansal28e68f82016-02-04 02:56:158545 session_deps_.proxy_service =
8546 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518547 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078548 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508549
8550 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108551 session_deps_.proxy_delegate = std::move(proxy_delegate);
[email protected]61b4efc2012-04-27 18:12:508552
danakj1fd259a02016-04-16 03:17:098553 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008554
bncdf80d44fd2016-07-15 20:27:418555 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458556 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:008557
bncdf80d44fd2016-07-15 20:27:418558 SpdySerializedFrame push_rst(
diannahu9904e272017-02-03 14:40:088559 spdy_util_.ConstructSpdyRstStream(2, ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008560
8561 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418562 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:008563 };
8564
bncdf80d44fd2016-07-15 20:27:418565 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158566 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008567
bncdf80d44fd2016-07-15 20:27:418568 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:008569
bncdf80d44fd2016-07-15 20:27:418570 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558571 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008572
8573 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418574 CreateMockRead(stream1_reply, 1, ASYNC),
8575 CreateMockRead(stream2_syn, 2, ASYNC),
8576 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598577 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008578 };
8579
rch8e6c6c42015-05-01 14:05:138580 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8581 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078582 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008583 // Negotiate SPDY to the proxy
8584 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368585 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078586 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008587
bnc87dcefc2017-05-25 12:47:588588 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198589 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:008590 TestCompletionCallback callback;
8591 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018592 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:008593
8594 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018595 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008596 const HttpResponseInfo* response = trans->GetResponseInfo();
8597
wezca1070932016-05-26 20:30:528598 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008599 EXPECT_TRUE(response->headers->IsKeepAlive());
8600
8601 EXPECT_EQ(200, response->headers->response_code());
8602 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8603
8604 std::string response_data;
8605 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018606 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:008607 EXPECT_EQ("hello!", response_data);
8608
8609 trans.reset();
8610 session->CloseAllConnections();
8611}
8612
tbansal8ef1d3e2016-02-03 04:05:428613// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8614// resources.
bncd16676a2016-07-20 16:23:018615TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158616 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:198617 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:158618 proxy_delegate->set_trusted_spdy_proxy(
8619 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8620
tbansal8ef1d3e2016-02-03 04:05:428621 HttpRequestInfo request;
8622
8623 request.method = "GET";
8624 request.url = GURL("http://www.example.org/");
8625
8626 // Configure against https proxy server "myproxy:70".
8627 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8628 BoundTestNetLog log;
8629 session_deps_.net_log = log.bound().net_log();
8630
8631 // Enable cross-origin push.
inlinechan894515af2016-12-09 02:40:108632 session_deps_.proxy_delegate = std::move(proxy_delegate);
tbansal8ef1d3e2016-02-03 04:05:428633
danakj1fd259a02016-04-16 03:17:098634 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428635
bncdf80d44fd2016-07-15 20:27:418636 SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:458637 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
tombergan5d22c182017-01-11 02:05:358638 SpdySerializedFrame stream2_priority(
8639 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:428640
8641 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418642 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:358643 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:428644 };
8645
bncdf80d44fd2016-07-15 20:27:418646 SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:158647 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428648
bncdf80d44fd2016-07-15 20:27:418649 SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:338650 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:498651
bncdf80d44fd2016-07-15 20:27:418652 SpdySerializedFrame stream1_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428653
bncdf80d44fd2016-07-15 20:27:418654 SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:158655 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:428656
bncdf80d44fd2016-07-15 20:27:418657 SpdySerializedFrame stream2_body(spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:428658
8659 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418660 CreateMockRead(stream1_reply, 1, ASYNC),
8661 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:358662 CreateMockRead(stream1_body, 4, ASYNC),
8663 CreateMockRead(stream2_body, 5, ASYNC),
8664 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:428665 };
8666
8667 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8668 arraysize(spdy_writes));
8669 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8670 // Negotiate SPDY to the proxy
8671 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368672 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:428673 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8674
bnc87dcefc2017-05-25 12:47:588675 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198676 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:428677 TestCompletionCallback callback;
8678 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:018679 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:428680
8681 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018682 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428683 const HttpResponseInfo* response = trans->GetResponseInfo();
8684
wezca1070932016-05-26 20:30:528685 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428686 EXPECT_TRUE(response->headers->IsKeepAlive());
8687
8688 EXPECT_EQ(200, response->headers->response_code());
8689 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8690
8691 std::string response_data;
8692 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018693 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:428694 EXPECT_EQ("hello!", response_data);
8695
8696 trans.reset();
8697 session->CloseAllConnections();
8698}
8699
[email protected]2df19bb2010-08-25 20:13:468700// Test HTTPS connections to a site with a bad certificate, going through an
8701// HTTPS proxy
bncd16676a2016-07-20 16:23:018702TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038703 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468704
8705 HttpRequestInfo request;
8706 request.method = "GET";
bncce36dca22015-04-21 22:11:238707 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468708
8709 // Attempt to fetch the URL from a server with a bad cert
8710 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178711 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8712 "Host: www.example.org:443\r\n"
8713 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468714 };
8715
8716 MockRead bad_cert_reads[] = {
8717 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068718 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468719 };
8720
8721 // Attempt to fetch the URL with a good cert
8722 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178723 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8724 "Host: www.example.org:443\r\n"
8725 "Proxy-Connection: keep-alive\r\n\r\n"),
8726 MockWrite("GET / HTTP/1.1\r\n"
8727 "Host: www.example.org\r\n"
8728 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468729 };
8730
8731 MockRead good_cert_reads[] = {
8732 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8733 MockRead("HTTP/1.0 200 OK\r\n"),
8734 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8735 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068736 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468737 };
8738
8739 StaticSocketDataProvider ssl_bad_certificate(
8740 bad_cert_reads, arraysize(bad_cert_reads),
8741 bad_cert_writes, arraysize(bad_cert_writes));
8742 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8743 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068744 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8745 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468746
8747 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078748 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8749 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8750 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468751
8752 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8754 session_deps_.socket_factory->AddSocketDataProvider(&data);
8755 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468756
[email protected]49639fa2011-12-20 23:22:418757 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468758
danakj1fd259a02016-04-16 03:17:098759 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168760 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468761
tfarina42834112016-09-22 13:38:208762 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018763 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468764
8765 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018766 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:468767
bnc691fda62016-08-12 00:43:168768 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018769 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468770
8771 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018772 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:468773
bnc691fda62016-08-12 00:43:168774 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468775
wezca1070932016-05-26 20:30:528776 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468777 EXPECT_EQ(100, response->headers->GetContentLength());
8778}
8779
bncd16676a2016-07-20 16:23:018780TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428781 HttpRequestInfo request;
8782 request.method = "GET";
bncce36dca22015-04-21 22:11:238783 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438784 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8785 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428786
danakj1fd259a02016-04-16 03:17:098787 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168788 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278789
[email protected]1c773ea12009-04-28 19:58:428790 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238791 MockWrite(
8792 "GET / HTTP/1.1\r\n"
8793 "Host: www.example.org\r\n"
8794 "Connection: keep-alive\r\n"
8795 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428796 };
8797
8798 // Lastly, the server responds with the actual content.
8799 MockRead data_reads[] = {
8800 MockRead("HTTP/1.0 200 OK\r\n"),
8801 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8802 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068803 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428804 };
8805
[email protected]31a2bfe2010-02-09 08:03:398806 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8807 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078808 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428809
[email protected]49639fa2011-12-20 23:22:418810 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428811
tfarina42834112016-09-22 13:38:208812 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428814
8815 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018816 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428817}
8818
bncd16676a2016-07-20 16:23:018819TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298820 HttpRequestInfo request;
8821 request.method = "GET";
bncce36dca22015-04-21 22:11:238822 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298823 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8824 "Chromium Ultra Awesome X Edition");
8825
rdsmith82957ad2015-09-16 19:42:038826 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168828 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278829
[email protected]da81f132010-08-18 23:39:298830 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178831 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8832 "Host: www.example.org:443\r\n"
8833 "Proxy-Connection: keep-alive\r\n"
8834 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298835 };
8836 MockRead data_reads[] = {
8837 // Return an error, so the transaction stops here (this test isn't
8838 // interested in the rest).
8839 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8840 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8841 MockRead("Proxy-Connection: close\r\n\r\n"),
8842 };
8843
8844 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8845 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078846 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298847
[email protected]49639fa2011-12-20 23:22:418848 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298849
tfarina42834112016-09-22 13:38:208850 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018851 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:298852
8853 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018854 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:298855}
8856
bncd16676a2016-07-20 16:23:018857TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428858 HttpRequestInfo request;
8859 request.method = "GET";
bncce36dca22015-04-21 22:11:238860 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:168861 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8862 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428863
danakj1fd259a02016-04-16 03:17:098864 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168865 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278866
[email protected]1c773ea12009-04-28 19:58:428867 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238868 MockWrite(
8869 "GET / HTTP/1.1\r\n"
8870 "Host: www.example.org\r\n"
8871 "Connection: keep-alive\r\n"
8872 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428873 };
8874
8875 // Lastly, the server responds with the actual content.
8876 MockRead data_reads[] = {
8877 MockRead("HTTP/1.0 200 OK\r\n"),
8878 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8879 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068880 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428881 };
8882
[email protected]31a2bfe2010-02-09 08:03:398883 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8884 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078885 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428886
[email protected]49639fa2011-12-20 23:22:418887 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428888
tfarina42834112016-09-22 13:38:208889 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018890 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428891
8892 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018893 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428894}
8895
bncd16676a2016-07-20 16:23:018896TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428897 HttpRequestInfo request;
8898 request.method = "POST";
bncce36dca22015-04-21 22:11:238899 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428900
danakj1fd259a02016-04-16 03:17:098901 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168902 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278903
[email protected]1c773ea12009-04-28 19:58:428904 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238905 MockWrite(
8906 "POST / HTTP/1.1\r\n"
8907 "Host: www.example.org\r\n"
8908 "Connection: keep-alive\r\n"
8909 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428910 };
8911
8912 // Lastly, the server responds with the actual content.
8913 MockRead data_reads[] = {
8914 MockRead("HTTP/1.0 200 OK\r\n"),
8915 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8916 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068917 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428918 };
8919
[email protected]31a2bfe2010-02-09 08:03:398920 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8921 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078922 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428923
[email protected]49639fa2011-12-20 23:22:418924 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428925
tfarina42834112016-09-22 13:38:208926 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018927 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428928
8929 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018930 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428931}
8932
bncd16676a2016-07-20 16:23:018933TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428934 HttpRequestInfo request;
8935 request.method = "PUT";
bncce36dca22015-04-21 22:11:238936 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428937
danakj1fd259a02016-04-16 03:17:098938 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168939 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278940
[email protected]1c773ea12009-04-28 19:58:428941 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238942 MockWrite(
8943 "PUT / HTTP/1.1\r\n"
8944 "Host: www.example.org\r\n"
8945 "Connection: keep-alive\r\n"
8946 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428947 };
8948
8949 // Lastly, the server responds with the actual content.
8950 MockRead data_reads[] = {
8951 MockRead("HTTP/1.0 200 OK\r\n"),
8952 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8953 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068954 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428955 };
8956
[email protected]31a2bfe2010-02-09 08:03:398957 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8958 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078959 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428960
[email protected]49639fa2011-12-20 23:22:418961 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428962
tfarina42834112016-09-22 13:38:208963 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018964 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:428965
8966 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018967 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:428968}
8969
bncd16676a2016-07-20 16:23:018970TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428971 HttpRequestInfo request;
8972 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238973 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428974
danakj1fd259a02016-04-16 03:17:098975 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168976 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278977
[email protected]1c773ea12009-04-28 19:58:428978 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138979 MockWrite("HEAD / HTTP/1.1\r\n"
8980 "Host: www.example.org\r\n"
8981 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428982 };
8983
8984 // Lastly, the server responds with the actual content.
8985 MockRead data_reads[] = {
8986 MockRead("HTTP/1.0 200 OK\r\n"),
8987 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8988 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068989 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428990 };
8991
[email protected]31a2bfe2010-02-09 08:03:398992 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8993 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078994 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428995
[email protected]49639fa2011-12-20 23:22:418996 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428997
tfarina42834112016-09-22 13:38:208998 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018999 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429000
9001 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019002 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429003}
9004
bncd16676a2016-07-20 16:23:019005TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429006 HttpRequestInfo request;
9007 request.method = "GET";
bncce36dca22015-04-21 22:11:239008 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429009 request.load_flags = LOAD_BYPASS_CACHE;
9010
danakj1fd259a02016-04-16 03:17:099011 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169012 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279013
[email protected]1c773ea12009-04-28 19:58:429014 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239015 MockWrite(
9016 "GET / HTTP/1.1\r\n"
9017 "Host: www.example.org\r\n"
9018 "Connection: keep-alive\r\n"
9019 "Pragma: no-cache\r\n"
9020 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429021 };
9022
9023 // Lastly, the server responds with the actual content.
9024 MockRead data_reads[] = {
9025 MockRead("HTTP/1.0 200 OK\r\n"),
9026 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9027 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069028 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429029 };
9030
[email protected]31a2bfe2010-02-09 08:03:399031 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9032 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079033 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429034
[email protected]49639fa2011-12-20 23:22:419035 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429036
tfarina42834112016-09-22 13:38:209037 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019038 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429039
9040 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019041 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429042}
9043
bncd16676a2016-07-20 16:23:019044TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429045 HttpRequestInfo request;
9046 request.method = "GET";
bncce36dca22015-04-21 22:11:239047 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429048 request.load_flags = LOAD_VALIDATE_CACHE;
9049
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]cb9bf6ca2011-01-28 13:15:279052
[email protected]1c773ea12009-04-28 19:58:429053 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239054 MockWrite(
9055 "GET / HTTP/1.1\r\n"
9056 "Host: www.example.org\r\n"
9057 "Connection: keep-alive\r\n"
9058 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429059 };
9060
9061 // Lastly, the server responds with the actual content.
9062 MockRead data_reads[] = {
9063 MockRead("HTTP/1.0 200 OK\r\n"),
9064 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9065 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069066 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429067 };
9068
[email protected]31a2bfe2010-02-09 08:03:399069 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9070 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079071 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429072
[email protected]49639fa2011-12-20 23:22:419073 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429074
tfarina42834112016-09-22 13:38:209075 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019076 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429077
9078 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019079 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429080}
9081
bncd16676a2016-07-20 16:23:019082TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429083 HttpRequestInfo request;
9084 request.method = "GET";
bncce36dca22015-04-21 22:11:239085 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439086 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:429087
danakj1fd259a02016-04-16 03:17:099088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169089 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279090
[email protected]1c773ea12009-04-28 19:58:429091 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239092 MockWrite(
9093 "GET / HTTP/1.1\r\n"
9094 "Host: www.example.org\r\n"
9095 "Connection: keep-alive\r\n"
9096 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429097 };
9098
9099 // Lastly, the server responds with the actual content.
9100 MockRead data_reads[] = {
9101 MockRead("HTTP/1.0 200 OK\r\n"),
9102 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9103 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069104 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429105 };
9106
[email protected]31a2bfe2010-02-09 08:03:399107 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9108 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079109 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429110
[email protected]49639fa2011-12-20 23:22:419111 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429112
tfarina42834112016-09-22 13:38:209113 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019114 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429115
9116 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019117 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429118}
9119
bncd16676a2016-07-20 16:23:019120TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479121 HttpRequestInfo request;
9122 request.method = "GET";
bncce36dca22015-04-21 22:11:239123 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439124 request.extra_headers.SetHeader("referer", "www.foo.com");
9125 request.extra_headers.SetHeader("hEllo", "Kitty");
9126 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:479127
danakj1fd259a02016-04-16 03:17:099128 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169129 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279130
[email protected]270c6412010-03-29 22:02:479131 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239132 MockWrite(
9133 "GET / HTTP/1.1\r\n"
9134 "Host: www.example.org\r\n"
9135 "Connection: keep-alive\r\n"
9136 "referer: www.foo.com\r\n"
9137 "hEllo: Kitty\r\n"
9138 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479139 };
9140
9141 // Lastly, the server responds with the actual content.
9142 MockRead data_reads[] = {
9143 MockRead("HTTP/1.0 200 OK\r\n"),
9144 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9145 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069146 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479147 };
9148
9149 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9150 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079151 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479152
[email protected]49639fa2011-12-20 23:22:419153 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479154
tfarina42834112016-09-22 13:38:209155 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019156 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479157
9158 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019159 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479160}
9161
bncd16676a2016-07-20 16:23:019162TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279163 HttpRequestInfo request;
9164 request.method = "GET";
bncce36dca22015-04-21 22:11:239165 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279166
rdsmith82957ad2015-09-16 19:42:039167 session_deps_.proxy_service =
9168 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519169 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079170 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029171
danakj1fd259a02016-04-16 03:17:099172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169173 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029174
[email protected]3cd17242009-06-23 02:59:029175 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9176 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9177
9178 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239179 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9180 MockWrite(
9181 "GET / HTTP/1.1\r\n"
9182 "Host: www.example.org\r\n"
9183 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029184
9185 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069186 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029187 MockRead("HTTP/1.0 200 OK\r\n"),
9188 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9189 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069190 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029191 };
9192
[email protected]31a2bfe2010-02-09 08:03:399193 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9194 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079195 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029196
[email protected]49639fa2011-12-20 23:22:419197 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029198
tfarina42834112016-09-22 13:38:209199 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019200 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029201
9202 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019203 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029204
bnc691fda62016-08-12 00:43:169205 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529206 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029207
tbansal2ecbbc72016-10-06 17:15:479208 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209209 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169210 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209211 TestLoadTimingNotReusedWithPac(load_timing_info,
9212 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9213
[email protected]3cd17242009-06-23 02:59:029214 std::string response_text;
bnc691fda62016-08-12 00:43:169215 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019216 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029217 EXPECT_EQ("Payload", response_text);
9218}
9219
bncd16676a2016-07-20 16:23:019220TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279221 HttpRequestInfo request;
9222 request.method = "GET";
bncce36dca22015-04-21 22:11:239223 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279224
rdsmith82957ad2015-09-16 19:42:039225 session_deps_.proxy_service =
9226 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519227 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079228 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029229
danakj1fd259a02016-04-16 03:17:099230 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169231 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029232
[email protected]3cd17242009-06-23 02:59:029233 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9234 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9235
9236 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239237 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9238 arraysize(write_buffer)),
9239 MockWrite(
9240 "GET / HTTP/1.1\r\n"
9241 "Host: www.example.org\r\n"
9242 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029243
9244 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019245 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9246 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359247 MockRead("HTTP/1.0 200 OK\r\n"),
9248 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9249 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069250 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359251 };
9252
[email protected]31a2bfe2010-02-09 08:03:399253 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9254 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079255 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359256
[email protected]8ddf8322012-02-23 18:08:069257 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079258 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359259
[email protected]49639fa2011-12-20 23:22:419260 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359261
tfarina42834112016-09-22 13:38:209262 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359264
9265 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019266 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359267
[email protected]029c83b62013-01-24 05:28:209268 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169269 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209270 TestLoadTimingNotReusedWithPac(load_timing_info,
9271 CONNECT_TIMING_HAS_SSL_TIMES);
9272
bnc691fda62016-08-12 00:43:169273 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529274 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479275 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359276
9277 std::string response_text;
bnc691fda62016-08-12 00:43:169278 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019279 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359280 EXPECT_EQ("Payload", response_text);
9281}
9282
bncd16676a2016-07-20 16:23:019283TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209284 HttpRequestInfo request;
9285 request.method = "GET";
bncce36dca22015-04-21 22:11:239286 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:209287
rdsmith82957ad2015-09-16 19:42:039288 session_deps_.proxy_service =
9289 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519290 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079291 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209292
danakj1fd259a02016-04-16 03:17:099293 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169294 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209295
9296 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9297 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9298
9299 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239300 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9301 MockWrite(
9302 "GET / HTTP/1.1\r\n"
9303 "Host: www.example.org\r\n"
9304 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209305
9306 MockRead data_reads[] = {
9307 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9308 MockRead("HTTP/1.0 200 OK\r\n"),
9309 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9310 MockRead("Payload"),
9311 MockRead(SYNCHRONOUS, OK)
9312 };
9313
9314 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9315 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079316 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209317
9318 TestCompletionCallback callback;
9319
tfarina42834112016-09-22 13:38:209320 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019321 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209322
9323 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019324 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209325
bnc691fda62016-08-12 00:43:169326 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529327 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209328
9329 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169330 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209331 TestLoadTimingNotReused(load_timing_info,
9332 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9333
9334 std::string response_text;
bnc691fda62016-08-12 00:43:169335 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019336 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209337 EXPECT_EQ("Payload", response_text);
9338}
9339
bncd16676a2016-07-20 16:23:019340TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279341 HttpRequestInfo request;
9342 request.method = "GET";
bncce36dca22015-04-21 22:11:239343 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279344
rdsmith82957ad2015-09-16 19:42:039345 session_deps_.proxy_service =
9346 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519347 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079348 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359349
danakj1fd259a02016-04-16 03:17:099350 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169351 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359352
[email protected]e0c27be2009-07-15 13:09:359353 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9354 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379355 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239356 0x05, // Version
9357 0x01, // Command (CONNECT)
9358 0x00, // Reserved.
9359 0x03, // Address type (DOMAINNAME).
9360 0x0F, // Length of domain (15)
9361 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9362 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:379363 };
[email protected]e0c27be2009-07-15 13:09:359364 const char kSOCKS5OkResponse[] =
9365 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
9366
9367 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239368 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9369 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
9370 MockWrite(
9371 "GET / HTTP/1.1\r\n"
9372 "Host: www.example.org\r\n"
9373 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359374
9375 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019376 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9377 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:359378 MockRead("HTTP/1.0 200 OK\r\n"),
9379 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9380 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069381 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359382 };
9383
[email protected]31a2bfe2010-02-09 08:03:399384 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9385 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079386 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359387
[email protected]49639fa2011-12-20 23:22:419388 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359389
tfarina42834112016-09-22 13:38:209390 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019391 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359392
9393 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019394 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359395
bnc691fda62016-08-12 00:43:169396 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529397 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479398 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359399
[email protected]029c83b62013-01-24 05:28:209400 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169401 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209402 TestLoadTimingNotReusedWithPac(load_timing_info,
9403 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9404
[email protected]e0c27be2009-07-15 13:09:359405 std::string response_text;
bnc691fda62016-08-12 00:43:169406 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019407 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359408 EXPECT_EQ("Payload", response_text);
9409}
9410
bncd16676a2016-07-20 16:23:019411TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279412 HttpRequestInfo request;
9413 request.method = "GET";
bncce36dca22015-04-21 22:11:239414 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279415
rdsmith82957ad2015-09-16 19:42:039416 session_deps_.proxy_service =
9417 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519418 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079419 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359420
danakj1fd259a02016-04-16 03:17:099421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169422 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:359423
[email protected]e0c27be2009-07-15 13:09:359424 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9425 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379426 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239427 0x05, // Version
9428 0x01, // Command (CONNECT)
9429 0x00, // Reserved.
9430 0x03, // Address type (DOMAINNAME).
9431 0x0F, // Length of domain (15)
9432 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9433 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379434 };
9435
[email protected]e0c27be2009-07-15 13:09:359436 const char kSOCKS5OkResponse[] =
9437 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9438
9439 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239440 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9441 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9442 arraysize(kSOCKS5OkRequest)),
9443 MockWrite(
9444 "GET / HTTP/1.1\r\n"
9445 "Host: www.example.org\r\n"
9446 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359447
9448 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019449 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9450 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029451 MockRead("HTTP/1.0 200 OK\r\n"),
9452 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9453 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069454 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029455 };
9456
[email protected]31a2bfe2010-02-09 08:03:399457 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9458 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079459 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029460
[email protected]8ddf8322012-02-23 18:08:069461 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029463
[email protected]49639fa2011-12-20 23:22:419464 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029465
tfarina42834112016-09-22 13:38:209466 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029468
9469 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019470 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029471
bnc691fda62016-08-12 00:43:169472 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529473 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479474 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:029475
[email protected]029c83b62013-01-24 05:28:209476 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169477 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209478 TestLoadTimingNotReusedWithPac(load_timing_info,
9479 CONNECT_TIMING_HAS_SSL_TIMES);
9480
[email protected]3cd17242009-06-23 02:59:029481 std::string response_text;
bnc691fda62016-08-12 00:43:169482 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019483 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029484 EXPECT_EQ("Payload", response_text);
9485}
9486
[email protected]448d4ca52012-03-04 04:12:239487namespace {
9488
[email protected]04e5be32009-06-26 20:00:319489// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069490
9491struct GroupNameTest {
9492 std::string proxy_server;
9493 std::string url;
9494 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189495 bool ssl;
[email protected]2d731a32010-04-29 01:04:069496};
9497
danakj1fd259a02016-04-16 03:17:099498std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:079499 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099500 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069501
bnc525e175a2016-06-20 12:36:409502 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539503 session->http_server_properties();
bnc3472afd2016-11-17 15:27:219504 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:129505 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:219506 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:429507 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469508 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069509
9510 return session;
9511}
9512
mmenkee65e7af2015-10-13 17:16:429513int GroupNameTransactionHelper(const std::string& url,
9514 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069515 HttpRequestInfo request;
9516 request.method = "GET";
9517 request.url = GURL(url);
[email protected]2d731a32010-04-29 01:04:069518
bnc691fda62016-08-12 00:43:169519 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:279520
[email protected]49639fa2011-12-20 23:22:419521 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069522
9523 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:209524 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:069525}
9526
[email protected]448d4ca52012-03-04 04:12:239527} // namespace
9528
bncd16676a2016-07-20 16:23:019529TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069530 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239531 {
9532 "", // unused
9533 "http://www.example.org/direct",
9534 "www.example.org:80",
9535 false,
9536 },
9537 {
9538 "", // unused
9539 "http://[2001:1418:13:1::25]/direct",
9540 "[2001:1418:13:1::25]:80",
9541 false,
9542 },
[email protected]04e5be32009-06-26 20:00:319543
bncce36dca22015-04-21 22:11:239544 // SSL Tests
9545 {
9546 "", // unused
9547 "https://www.example.org/direct_ssl",
9548 "ssl/www.example.org:443",
9549 true,
9550 },
9551 {
9552 "", // unused
9553 "https://[2001:1418:13:1::25]/direct",
9554 "ssl/[2001:1418:13:1::25]:443",
9555 true,
9556 },
9557 {
9558 "", // unused
bncaa60ff402016-06-22 19:12:429559 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239560 "ssl/host.with.alternate:443",
9561 true,
9562 },
[email protected]2d731a32010-04-29 01:04:069563 };
[email protected]2ff8b312010-04-26 22:20:549564
viettrungluue4a8b882014-10-16 06:17:389565 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039566 session_deps_.proxy_service =
9567 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099568 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409569 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069570
mmenkee65e7af2015-10-13 17:16:429571 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289572 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:589573 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:139574 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:589575 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:199576 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:029577 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9578 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489579 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069580
9581 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429582 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189583 if (tests[i].ssl)
9584 EXPECT_EQ(tests[i].expected_group_name,
9585 ssl_conn_pool->last_group_name_received());
9586 else
9587 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289588 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069589 }
[email protected]2d731a32010-04-29 01:04:069590}
9591
bncd16676a2016-07-20 16:23:019592TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069593 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239594 {
9595 "http_proxy",
9596 "http://www.example.org/http_proxy_normal",
9597 "www.example.org:80",
9598 false,
9599 },
[email protected]2d731a32010-04-29 01:04:069600
bncce36dca22015-04-21 22:11:239601 // SSL Tests
9602 {
9603 "http_proxy",
9604 "https://www.example.org/http_connect_ssl",
9605 "ssl/www.example.org:443",
9606 true,
9607 },
[email protected]af3490e2010-10-16 21:02:299608
bncce36dca22015-04-21 22:11:239609 {
9610 "http_proxy",
bncaa60ff402016-06-22 19:12:429611 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239612 "ssl/host.with.alternate:443",
9613 true,
9614 },
[email protected]45499252013-01-23 17:12:569615
bncce36dca22015-04-21 22:11:239616 {
9617 "http_proxy",
9618 "ftp://ftp.google.com/http_proxy_normal",
9619 "ftp/ftp.google.com:21",
9620 false,
9621 },
[email protected]2d731a32010-04-29 01:04:069622 };
9623
viettrungluue4a8b882014-10-16 06:17:389624 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039625 session_deps_.proxy_service =
9626 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099627 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409628 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:069629
mmenkee65e7af2015-10-13 17:16:429630 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069631
[email protected]e60e47a2010-07-14 03:37:189632 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139633 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349634 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139635 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349636 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:199637 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399638 mock_pool_manager->SetSocketPoolForHTTPProxy(
9639 proxy_host, base::WrapUnique(http_proxy_pool));
9640 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9641 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489642 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069643
9644 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429645 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189646 if (tests[i].ssl)
9647 EXPECT_EQ(tests[i].expected_group_name,
9648 ssl_conn_pool->last_group_name_received());
9649 else
9650 EXPECT_EQ(tests[i].expected_group_name,
9651 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069652 }
[email protected]2d731a32010-04-29 01:04:069653}
9654
bncd16676a2016-07-20 16:23:019655TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069656 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239657 {
9658 "socks4://socks_proxy:1080",
9659 "http://www.example.org/socks4_direct",
9660 "socks4/www.example.org:80",
9661 false,
9662 },
9663 {
9664 "socks5://socks_proxy:1080",
9665 "http://www.example.org/socks5_direct",
9666 "socks5/www.example.org:80",
9667 false,
9668 },
[email protected]2d731a32010-04-29 01:04:069669
bncce36dca22015-04-21 22:11:239670 // SSL Tests
9671 {
9672 "socks4://socks_proxy:1080",
9673 "https://www.example.org/socks4_ssl",
9674 "socks4/ssl/www.example.org:443",
9675 true,
9676 },
9677 {
9678 "socks5://socks_proxy:1080",
9679 "https://www.example.org/socks5_ssl",
9680 "socks5/ssl/www.example.org:443",
9681 true,
9682 },
[email protected]af3490e2010-10-16 21:02:299683
bncce36dca22015-04-21 22:11:239684 {
9685 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429686 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239687 "socks4/ssl/host.with.alternate:443",
9688 true,
9689 },
[email protected]04e5be32009-06-26 20:00:319690 };
9691
viettrungluue4a8b882014-10-16 06:17:389692 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039693 session_deps_.proxy_service =
9694 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099695 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:409696 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:029697
mmenkee65e7af2015-10-13 17:16:429698 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319699
[email protected]e60e47a2010-07-14 03:37:189700 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139701 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349702 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139703 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349704 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:199705 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:399706 mock_pool_manager->SetSocketPoolForSOCKSProxy(
9707 proxy_host, base::WrapUnique(socks_conn_pool));
9708 mock_pool_manager->SetSocketPoolForSSLWithProxy(
9709 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:489710 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319711
bnc691fda62016-08-12 00:43:169712 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:319713
[email protected]2d731a32010-04-29 01:04:069714 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429715 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189716 if (tests[i].ssl)
9717 EXPECT_EQ(tests[i].expected_group_name,
9718 ssl_conn_pool->last_group_name_received());
9719 else
9720 EXPECT_EQ(tests[i].expected_group_name,
9721 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319722 }
9723}
9724
bncd16676a2016-07-20 16:23:019725TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279726 HttpRequestInfo request;
9727 request.method = "GET";
bncce36dca22015-04-21 22:11:239728 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279729
rdsmith82957ad2015-09-16 19:42:039730 session_deps_.proxy_service =
9731 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329732
[email protected]69719062010-01-05 20:09:219733 // This simulates failure resolving all hostnames; that means we will fail
9734 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079735 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329736
danakj1fd259a02016-04-16 03:17:099737 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169738 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:259739
[email protected]49639fa2011-12-20 23:22:419740 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259741
tfarina42834112016-09-22 13:38:209742 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019743 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:259744
[email protected]9172a982009-06-06 00:30:259745 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019746 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:259747}
9748
[email protected]685af592010-05-11 19:31:249749// Base test to make sure that when the load flags for a request specify to
9750// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029751void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079752 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279753 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:109754 HttpRequestInfo request_info;
9755 request_info.method = "GET";
9756 request_info.load_flags = load_flags;
9757 request_info.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279758
[email protected]a2c2fb92009-07-18 07:31:049759 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:199760 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:329761
danakj1fd259a02016-04-16 03:17:099762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169763 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:289764
bncce36dca22015-04-21 22:11:239765 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289766 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299767 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:109768 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:079769 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239770 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109771 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:209772 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019773 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:479774 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019775 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289776
9777 // Verify that it was added to host cache, by doing a subsequent async lookup
9778 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:109779 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:079780 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239781 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:109782 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:209783 NetLogWithSource());
robpercival214763f2016-07-01 23:27:019784 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:289785
bncce36dca22015-04-21 22:11:239786 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289787 // we can tell if the next lookup hit the cache, or the "network".
9788 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239789 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289790
9791 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9792 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069793 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399794 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079795 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289796
[email protected]3b9cca42009-06-16 01:08:289797 // Run the request.
tfarina42834112016-09-22 13:38:209798 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019799 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:419800 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289801
9802 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239803 // "www.example.org".
robpercival214763f2016-07-01 23:27:019804 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:289805}
9806
[email protected]685af592010-05-11 19:31:249807// There are multiple load flags that should trigger the host cache bypass.
9808// Test each in isolation:
bncd16676a2016-07-20 16:23:019809TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249810 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9811}
9812
bncd16676a2016-07-20 16:23:019813TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249814 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9815}
9816
bncd16676a2016-07-20 16:23:019817TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249818 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9819}
9820
[email protected]0877e3d2009-10-17 22:29:579821// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:019822TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579823 HttpRequestInfo request;
9824 request.method = "GET";
9825 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579826
9827 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069828 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579829 };
[email protected]31a2bfe2010-02-09 08:03:399830 StaticSocketDataProvider data(NULL, 0,
9831 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079832 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099833 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579834
[email protected]49639fa2011-12-20 23:22:419835 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579836
bnc691fda62016-08-12 00:43:169837 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579838
tfarina42834112016-09-22 13:38:209839 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019840 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579841
9842 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019843 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:599844
9845 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169846 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599847 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579848}
9849
zmo9528c9f42015-08-04 22:12:089850// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:019851TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579852 HttpRequestInfo request;
9853 request.method = "GET";
9854 request.url = GURL("http://www.foo.com/");
[email protected]0877e3d2009-10-17 22:29:579855
9856 MockRead data_reads[] = {
9857 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069858 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579859 };
9860
[email protected]31a2bfe2010-02-09 08:03:399861 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079862 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099863 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579864
[email protected]49639fa2011-12-20 23:22:419865 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579866
bnc691fda62016-08-12 00:43:169867 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579868
tfarina42834112016-09-22 13:38:209869 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019870 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579871
9872 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019873 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089874
bnc691fda62016-08-12 00:43:169875 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529876 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089877
wezca1070932016-05-26 20:30:529878 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089879 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9880
9881 std::string response_data;
bnc691fda62016-08-12 00:43:169882 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:019883 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:089884 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599885
9886 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:169887 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:599888 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579889}
9890
9891// Make sure that a dropped connection while draining the body for auth
9892// restart does the right thing.
bncd16676a2016-07-20 16:23:019893TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579894 HttpRequestInfo request;
9895 request.method = "GET";
bncce36dca22015-04-21 22:11:239896 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579897
9898 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239899 MockWrite(
9900 "GET / HTTP/1.1\r\n"
9901 "Host: www.example.org\r\n"
9902 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579903 };
9904
9905 MockRead data_reads1[] = {
9906 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9907 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9908 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9909 MockRead("Content-Length: 14\r\n\r\n"),
9910 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069911 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579912 };
9913
[email protected]31a2bfe2010-02-09 08:03:399914 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9915 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079916 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579917
bnc691fda62016-08-12 00:43:169918 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:579919 // be issuing -- the final header line contains the credentials.
9920 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239921 MockWrite(
9922 "GET / HTTP/1.1\r\n"
9923 "Host: www.example.org\r\n"
9924 "Connection: keep-alive\r\n"
9925 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579926 };
9927
9928 // Lastly, the server responds with the actual content.
9929 MockRead data_reads2[] = {
9930 MockRead("HTTP/1.1 200 OK\r\n"),
9931 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9932 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069933 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579934 };
9935
[email protected]31a2bfe2010-02-09 08:03:399936 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9937 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079938 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579940
[email protected]49639fa2011-12-20 23:22:419941 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579942
bnc691fda62016-08-12 00:43:169943 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:509944
tfarina42834112016-09-22 13:38:209945 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579947
9948 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019949 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579950
bnc691fda62016-08-12 00:43:169951 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529952 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049953 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579954
[email protected]49639fa2011-12-20 23:22:419955 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579956
bnc691fda62016-08-12 00:43:169957 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:019958 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579959
9960 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019961 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:579962
bnc691fda62016-08-12 00:43:169963 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529964 ASSERT_TRUE(response);
9965 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579966 EXPECT_EQ(100, response->headers->GetContentLength());
9967}
9968
9969// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:019970TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039971 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579972
9973 HttpRequestInfo request;
9974 request.method = "GET";
bncce36dca22015-04-21 22:11:239975 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579976
9977 MockRead proxy_reads[] = {
9978 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069979 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579980 };
9981
[email protected]31a2bfe2010-02-09 08:03:399982 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069983 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579984
[email protected]bb88e1d32013-05-03 23:11:079985 session_deps_.socket_factory->AddSocketDataProvider(&data);
9986 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579987
[email protected]49639fa2011-12-20 23:22:419988 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579989
[email protected]bb88e1d32013-05-03 23:11:079990 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579991
danakj1fd259a02016-04-16 03:17:099992 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169993 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:579994
tfarina42834112016-09-22 13:38:209995 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019996 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:579997
9998 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019999 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710000}
10001
bncd16676a2016-07-20 16:23:0110002TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610003 HttpRequestInfo request;
10004 request.method = "GET";
bncce36dca22015-04-21 22:11:2310005 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:4610006
danakj1fd259a02016-04-16 03:17:0910007 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610008 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710009
[email protected]e22e1362009-11-23 21:31:1210010 MockRead data_reads[] = {
10011 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610012 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210013 };
[email protected]9492e4a2010-02-24 00:58:4610014
10015 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710016 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610017
[email protected]49639fa2011-12-20 23:22:4110018 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610019
tfarina42834112016-09-22 13:38:2010020 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110021 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610022
robpercival214763f2016-07-01 23:27:0110023 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610024
bnc691fda62016-08-12 00:43:1610025 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210026 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610027
wezca1070932016-05-26 20:30:5210028 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610029 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10030
10031 std::string response_data;
bnc691fda62016-08-12 00:43:1610032 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110033 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210034}
10035
bncd16676a2016-07-20 16:23:0110036TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510037 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210038 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410039 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110040 UploadFileElementReader::ScopedOverridingContentLengthForTests
10041 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310042
danakj1fd259a02016-04-16 03:17:0910043 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910044 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410045 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710046 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210047 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710048
10049 HttpRequestInfo request;
10050 request.method = "POST";
bncce36dca22015-04-21 22:11:2310051 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710052 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710053
danakj1fd259a02016-04-16 03:17:0910054 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610055 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310056
10057 MockRead data_reads[] = {
10058 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10059 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610060 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310061 };
[email protected]31a2bfe2010-02-09 08:03:3910062 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710063 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310064
[email protected]49639fa2011-12-20 23:22:4110065 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310066
tfarina42834112016-09-22 13:38:2010067 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110068 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310069
10070 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110071 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310072
bnc691fda62016-08-12 00:43:1610073 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210074 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310075
maksim.sisove869bf52016-06-23 17:11:5210076 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310077
[email protected]dd3aa792013-07-16 19:10:2310078 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310079}
10080
bncd16676a2016-07-20 16:23:0110081TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510082 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210083 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610084 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810085 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10086 base::WriteFile(temp_file, temp_file_content.c_str(),
10087 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110088 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610089
danakj1fd259a02016-04-16 03:17:0910090 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910091 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410092 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710093 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210094 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710095
10096 HttpRequestInfo request;
10097 request.method = "POST";
bncce36dca22015-04-21 22:11:2310098 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710099 request.upload_data_stream = &upload_data_stream;
[email protected]329b68b2012-11-14 17:54:2710100
[email protected]999dd8c2013-11-12 06:45:5410101 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910102 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610103 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610104
[email protected]999dd8c2013-11-12 06:45:5410105 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710106 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610107
[email protected]49639fa2011-12-20 23:22:4110108 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610109
tfarina42834112016-09-22 13:38:2010110 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110111 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610112
10113 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110114 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610115
[email protected]dd3aa792013-07-16 19:10:2310116 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610117}
10118
bncd16676a2016-07-20 16:23:0110119TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310120 class FakeUploadElementReader : public UploadElementReader {
10121 public:
10122 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:2010123 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:0310124
10125 const CompletionCallback& callback() const { return callback_; }
10126
10127 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:2010128 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310129 callback_ = callback;
10130 return ERR_IO_PENDING;
10131 }
avibf0746c2015-12-09 19:53:1410132 uint64_t GetContentLength() const override { return 0; }
10133 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010134 int Read(IOBuffer* buf,
10135 int buf_length,
10136 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:0310137 return ERR_FAILED;
10138 }
10139
10140 private:
10141 CompletionCallback callback_;
10142 };
10143
10144 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910145 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10146 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210147 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310148
10149 HttpRequestInfo request;
10150 request.method = "POST";
bncce36dca22015-04-21 22:11:2310151 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310152 request.upload_data_stream = &upload_data_stream;
[email protected]02cad5d2013-10-02 08:14:0310153
danakj1fd259a02016-04-16 03:17:0910154 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810155 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910156 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310157
10158 StaticSocketDataProvider data;
10159 session_deps_.socket_factory->AddSocketDataProvider(&data);
10160
10161 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010162 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110163 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510164 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310165
10166 // Transaction is pending on request body initialization.
10167 ASSERT_FALSE(fake_reader->callback().is_null());
10168
10169 // Return Init()'s result after the transaction gets destroyed.
10170 trans.reset();
10171 fake_reader->callback().Run(OK); // Should not crash.
10172}
10173
[email protected]aeefc9e82010-02-19 16:18:2710174// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110175TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710176 HttpRequestInfo request;
10177 request.method = "GET";
bncce36dca22015-04-21 22:11:2310178 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:2710179
10180 // First transaction will request a resource and receive a Basic challenge
10181 // with realm="first_realm".
10182 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310183 MockWrite(
10184 "GET / HTTP/1.1\r\n"
10185 "Host: www.example.org\r\n"
10186 "Connection: keep-alive\r\n"
10187 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710188 };
10189 MockRead data_reads1[] = {
10190 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10191 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10192 "\r\n"),
10193 };
10194
bnc691fda62016-08-12 00:43:1610195 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710196 // for first_realm. The server will reject and provide a challenge with
10197 // second_realm.
10198 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310199 MockWrite(
10200 "GET / HTTP/1.1\r\n"
10201 "Host: www.example.org\r\n"
10202 "Connection: keep-alive\r\n"
10203 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10204 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710205 };
10206 MockRead data_reads2[] = {
10207 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10208 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10209 "\r\n"),
10210 };
10211
10212 // This again fails, and goes back to first_realm. Make sure that the
10213 // entry is removed from cache.
10214 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310215 MockWrite(
10216 "GET / HTTP/1.1\r\n"
10217 "Host: www.example.org\r\n"
10218 "Connection: keep-alive\r\n"
10219 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10220 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710221 };
10222 MockRead data_reads3[] = {
10223 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10224 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10225 "\r\n"),
10226 };
10227
10228 // Try one last time (with the correct password) and get the resource.
10229 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310230 MockWrite(
10231 "GET / HTTP/1.1\r\n"
10232 "Host: www.example.org\r\n"
10233 "Connection: keep-alive\r\n"
10234 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10235 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710236 };
10237 MockRead data_reads4[] = {
10238 MockRead("HTTP/1.1 200 OK\r\n"
10239 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010240 "Content-Length: 5\r\n"
10241 "\r\n"
10242 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710243 };
10244
10245 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10246 data_writes1, arraysize(data_writes1));
10247 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
10248 data_writes2, arraysize(data_writes2));
10249 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
10250 data_writes3, arraysize(data_writes3));
10251 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
10252 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:0710253 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10254 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10255 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10256 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710257
[email protected]49639fa2011-12-20 23:22:4110258 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710259
danakj1fd259a02016-04-16 03:17:0910260 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610261 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010262
[email protected]aeefc9e82010-02-19 16:18:2710263 // Issue the first request with Authorize headers. There should be a
10264 // password prompt for first_realm waiting to be filled in after the
10265 // transaction completes.
tfarina42834112016-09-22 13:38:2010266 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110267 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710268 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110269 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610270 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210271 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410272 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210273 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410274 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310275 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410276 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910277 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710278
10279 // Issue the second request with an incorrect password. There should be a
10280 // password prompt for second_realm waiting to be filled in after the
10281 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110282 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610283 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10284 callback2.callback());
robpercival214763f2016-07-01 23:27:0110285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710286 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110287 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610288 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210289 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410290 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210291 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410292 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310293 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410294 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910295 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710296
10297 // Issue the third request with another incorrect password. There should be
10298 // a password prompt for first_realm waiting to be filled in. If the password
10299 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10300 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110301 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610302 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10303 callback3.callback());
robpercival214763f2016-07-01 23:27:0110304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710305 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110306 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610307 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210308 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410309 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210310 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410311 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310312 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410313 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910314 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710315
10316 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110317 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610318 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10319 callback4.callback());
robpercival214763f2016-07-01 23:27:0110320 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710321 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110322 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610323 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210324 ASSERT_TRUE(response);
10325 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2710326}
10327
Bence Béky230ac612017-08-30 19:17:0810328// Regression test for https://crbug.com/754395.
10329TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
10330 MockRead data_reads[] = {
10331 MockRead("HTTP/1.1 200 OK\r\n"),
10332 MockRead(kAlternativeServiceHttpHeader),
10333 MockRead("\r\n"),
10334 MockRead("hello world"),
10335 MockRead(SYNCHRONOUS, OK),
10336 };
10337
10338 HttpRequestInfo request;
10339 request.method = "GET";
10340 request.url = GURL("https://www.example.org/");
10341
10342 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10343 session_deps_.socket_factory->AddSocketDataProvider(&data);
10344
10345 SSLSocketDataProvider ssl(ASYNC, OK);
10346 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10347 ASSERT_TRUE(ssl.cert);
10348 ssl.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
10349 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10350
10351 TestCompletionCallback callback;
10352
10353 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10354 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10355
10356 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10357 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10358
10359 url::SchemeHostPort test_server(request.url);
10360 HttpServerProperties* http_server_properties =
10361 session->http_server_properties();
10362 EXPECT_TRUE(
10363 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10364
10365 EXPECT_THAT(callback.WaitForResult(), IsOk());
10366
10367 const HttpResponseInfo* response = trans.GetResponseInfo();
10368 ASSERT_TRUE(response);
10369 ASSERT_TRUE(response->headers);
10370 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10371 EXPECT_FALSE(response->was_fetched_via_spdy);
10372 EXPECT_FALSE(response->was_alpn_negotiated);
10373
10374 std::string response_data;
10375 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
10376 EXPECT_EQ("hello world", response_data);
10377
10378 EXPECT_TRUE(
10379 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
10380}
10381
bncd16676a2016-07-20 16:23:0110382TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5210383 MockRead data_reads[] = {
10384 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310385 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5210386 MockRead("\r\n"),
10387 MockRead("hello world"),
10388 MockRead(SYNCHRONOUS, OK),
10389 };
10390
10391 HttpRequestInfo request;
10392 request.method = "GET";
bncb26024382016-06-29 02:39:4510393 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210394
10395 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210396 session_deps_.socket_factory->AddSocketDataProvider(&data);
10397
bncb26024382016-06-29 02:39:4510398 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810399 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10400 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510401 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10402
bncc958faa2015-07-31 18:14:5210403 TestCompletionCallback callback;
10404
danakj1fd259a02016-04-16 03:17:0910405 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210407
tfarina42834112016-09-22 13:38:2010408 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110409 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210410
bncb26024382016-06-29 02:39:4510411 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010412 HttpServerProperties* http_server_properties =
10413 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410414 EXPECT_TRUE(
10415 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210416
robpercival214763f2016-07-01 23:27:0110417 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210418
bnc691fda62016-08-12 00:43:1610419 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210420 ASSERT_TRUE(response);
10421 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210422 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10423 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210424 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210425
10426 std::string response_data;
bnc691fda62016-08-12 00:43:1610427 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210428 EXPECT_EQ("hello world", response_data);
10429
zhongyic4de03032017-05-19 04:07:3410430 AlternativeServiceInfoVector alternative_service_info_vector =
10431 http_server_properties->GetAlternativeServiceInfos(test_server);
10432 ASSERT_EQ(1u, alternative_service_info_vector.size());
10433 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
10434 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410435 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5210436}
10437
bnce3dd56f2016-06-01 10:37:1110438// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0110439TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110440 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1110441 MockRead data_reads[] = {
10442 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310443 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1110444 MockRead("\r\n"),
10445 MockRead("hello world"),
10446 MockRead(SYNCHRONOUS, OK),
10447 };
10448
10449 HttpRequestInfo request;
10450 request.method = "GET";
10451 request.url = GURL("http://www.example.org/");
10452 request.load_flags = 0;
10453
10454 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10455 session_deps_.socket_factory->AddSocketDataProvider(&data);
10456
10457 TestCompletionCallback callback;
10458
10459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610460 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110461
10462 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010463 HttpServerProperties* http_server_properties =
10464 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410465 EXPECT_TRUE(
10466 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110467
tfarina42834112016-09-22 13:38:2010468 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10470 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1110471
bnc691fda62016-08-12 00:43:1610472 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1110473 ASSERT_TRUE(response);
10474 ASSERT_TRUE(response->headers);
10475 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10476 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210477 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1110478
10479 std::string response_data;
bnc691fda62016-08-12 00:43:1610480 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1110481 EXPECT_EQ("hello world", response_data);
10482
zhongyic4de03032017-05-19 04:07:3410483 EXPECT_TRUE(
10484 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1110485}
10486
bnca86731e2017-04-17 12:31:2810487// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2510488// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0110489TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2510490 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2810491 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4510492
bnc8bef8da22016-05-30 01:28:2510493 HttpRequestInfo request;
10494 request.method = "GET";
bncb26024382016-06-29 02:39:4510495 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2510496 request.load_flags = 0;
10497
10498 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10499 StaticSocketDataProvider first_data;
10500 first_data.set_connect_data(mock_connect);
10501 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510502 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610503 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510504 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2510505
10506 MockRead data_reads[] = {
10507 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10508 MockRead(ASYNC, OK),
10509 };
10510 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10511 0);
10512 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10513
10514 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10515
bnc525e175a2016-06-20 12:36:4010516 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510517 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110518 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
10519 444);
bnc8bef8da22016-05-30 01:28:2510520 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110521 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2510522 url::SchemeHostPort(request.url), alternative_service, expiration);
10523
bnc691fda62016-08-12 00:43:1610524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2510525 TestCompletionCallback callback;
10526
tfarina42834112016-09-22 13:38:2010527 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2510528 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110529 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2510530}
10531
bnce3dd56f2016-06-01 10:37:1110532// Regression test for https://crbug.com/615497:
10533// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0110534TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1110535 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1110536 HttpRequestInfo request;
10537 request.method = "GET";
10538 request.url = GURL("http://www.example.org/");
10539 request.load_flags = 0;
10540
10541 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10542 StaticSocketDataProvider first_data;
10543 first_data.set_connect_data(mock_connect);
10544 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10545
10546 MockRead data_reads[] = {
10547 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10548 MockRead(ASYNC, OK),
10549 };
10550 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10551 0);
10552 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10553
10554 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10555
bnc525e175a2016-06-20 12:36:4010556 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110557 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110558 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1110559 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110560 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1110561 url::SchemeHostPort(request.url), alternative_service, expiration);
10562
bnc691fda62016-08-12 00:43:1610563 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1110564 TestCompletionCallback callback;
10565
tfarina42834112016-09-22 13:38:2010566 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1110567 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0110568 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1110569}
10570
bncd16676a2016-07-20 16:23:0110571TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0810572 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910573 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010574 HttpServerProperties* http_server_properties =
10575 session->http_server_properties();
bncb26024382016-06-29 02:39:4510576 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2110577 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0810578 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110579 http_server_properties->SetQuicAlternativeService(
10580 test_server, alternative_service, expiration,
10581 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3410582 EXPECT_EQ(
10583 1u,
10584 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0810585
10586 // Send a clear header.
10587 MockRead data_reads[] = {
10588 MockRead("HTTP/1.1 200 OK\r\n"),
10589 MockRead("Alt-Svc: clear\r\n"),
10590 MockRead("\r\n"),
10591 MockRead("hello world"),
10592 MockRead(SYNCHRONOUS, OK),
10593 };
10594 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10595 session_deps_.socket_factory->AddSocketDataProvider(&data);
10596
bncb26024382016-06-29 02:39:4510597 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810598 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10599 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510600 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10601
bnc4f575852015-10-14 18:35:0810602 HttpRequestInfo request;
10603 request.method = "GET";
bncb26024382016-06-29 02:39:4510604 request.url = GURL("https://www.example.org/");
bnc4f575852015-10-14 18:35:0810605
10606 TestCompletionCallback callback;
10607
bnc691fda62016-08-12 00:43:1610608 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0810609
tfarina42834112016-09-22 13:38:2010610 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110611 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0810612
bnc691fda62016-08-12 00:43:1610613 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210614 ASSERT_TRUE(response);
10615 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810616 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10617 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210618 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0810619
10620 std::string response_data;
bnc691fda62016-08-12 00:43:1610621 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0810622 EXPECT_EQ("hello world", response_data);
10623
zhongyic4de03032017-05-19 04:07:3410624 EXPECT_TRUE(
10625 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0810626}
10627
bncd16676a2016-07-20 16:23:0110628TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5210629 MockRead data_reads[] = {
10630 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4310631 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
10632 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210633 MockRead("hello world"),
10634 MockRead(SYNCHRONOUS, OK),
10635 };
10636
10637 HttpRequestInfo request;
10638 request.method = "GET";
bncb26024382016-06-29 02:39:4510639 request.url = GURL("https://www.example.org/");
bncc958faa2015-07-31 18:14:5210640
10641 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
bncc958faa2015-07-31 18:14:5210642 session_deps_.socket_factory->AddSocketDataProvider(&data);
10643
bncb26024382016-06-29 02:39:4510644 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0810645 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
10646 ASSERT_TRUE(ssl.cert);
bncb26024382016-06-29 02:39:4510647 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10648
bncc958faa2015-07-31 18:14:5210649 TestCompletionCallback callback;
10650
danakj1fd259a02016-04-16 03:17:0910651 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610652 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5210653
tfarina42834112016-09-22 13:38:2010654 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5210656
bncb26024382016-06-29 02:39:4510657 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4010658 HttpServerProperties* http_server_properties =
10659 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3410660 EXPECT_TRUE(
10661 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5210662
robpercival214763f2016-07-01 23:27:0110663 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5210664
bnc691fda62016-08-12 00:43:1610665 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210666 ASSERT_TRUE(response);
10667 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210668 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10669 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5210670 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5210671
10672 std::string response_data;
bnc691fda62016-08-12 00:43:1610673 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5210674 EXPECT_EQ("hello world", response_data);
10675
zhongyic4de03032017-05-19 04:07:3410676 AlternativeServiceInfoVector alternative_service_info_vector =
10677 http_server_properties->GetAlternativeServiceInfos(test_server);
10678 ASSERT_EQ(2u, alternative_service_info_vector.size());
10679
10680 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
10681 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410682 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410683 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
10684 1234);
10685 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5410686 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5210687}
10688
bncd16676a2016-07-20 16:23:0110689TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610690 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210691 HostPortPair alternative("alternative.example.org", 443);
10692 std::string origin_url = "https://origin.example.org:443";
10693 std::string alternative_url = "https://alternative.example.org:443";
10694
10695 // Negotiate HTTP/1.1 with alternative.example.org.
10696 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610697 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210698 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10699
10700 // HTTP/1.1 data for request.
10701 MockWrite http_writes[] = {
10702 MockWrite("GET / HTTP/1.1\r\n"
10703 "Host: alternative.example.org\r\n"
10704 "Connection: keep-alive\r\n\r\n"),
10705 };
10706
10707 MockRead http_reads[] = {
10708 MockRead("HTTP/1.1 200 OK\r\n"
10709 "Content-Type: text/html; charset=iso-8859-1\r\n"
10710 "Content-Length: 40\r\n\r\n"
10711 "first HTTP/1.1 response from alternative"),
10712 };
10713 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10714 http_writes, arraysize(http_writes));
10715 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10716
10717 StaticSocketDataProvider data_refused;
10718 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10719 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10720
zhongyi3d4a55e72016-04-22 20:36:4610721 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0910722 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010723 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210724 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110725 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0210726 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110727 http_server_properties->SetQuicAlternativeService(
10728 server, alternative_service, expiration,
10729 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0210730 // Mark the QUIC alternative service as broken.
10731 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10732
zhongyi48704c182015-12-07 07:52:0210733 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610734 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210735 request.method = "GET";
10736 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210737 TestCompletionCallback callback;
10738 NetErrorDetails details;
10739 EXPECT_FALSE(details.quic_broken);
10740
tfarina42834112016-09-22 13:38:2010741 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610742 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210743 EXPECT_TRUE(details.quic_broken);
10744}
10745
bncd16676a2016-07-20 16:23:0110746TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610747 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210748 HostPortPair alternative1("alternative1.example.org", 443);
10749 HostPortPair alternative2("alternative2.example.org", 443);
10750 std::string origin_url = "https://origin.example.org:443";
10751 std::string alternative_url1 = "https://alternative1.example.org:443";
10752 std::string alternative_url2 = "https://alternative2.example.org:443";
10753
10754 // Negotiate HTTP/1.1 with alternative1.example.org.
10755 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610756 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0210757 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10758
10759 // HTTP/1.1 data for request.
10760 MockWrite http_writes[] = {
10761 MockWrite("GET / HTTP/1.1\r\n"
10762 "Host: alternative1.example.org\r\n"
10763 "Connection: keep-alive\r\n\r\n"),
10764 };
10765
10766 MockRead http_reads[] = {
10767 MockRead("HTTP/1.1 200 OK\r\n"
10768 "Content-Type: text/html; charset=iso-8859-1\r\n"
10769 "Content-Length: 40\r\n\r\n"
10770 "first HTTP/1.1 response from alternative1"),
10771 };
10772 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10773 http_writes, arraysize(http_writes));
10774 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10775
10776 StaticSocketDataProvider data_refused;
10777 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10778 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10779
danakj1fd259a02016-04-16 03:17:0910780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010781 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210782 session->http_server_properties();
10783
zhongyi3d4a55e72016-04-22 20:36:4610784 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210785 AlternativeServiceInfoVector alternative_service_info_vector;
10786 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10787
bnc3472afd2016-11-17 15:27:2110788 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2110789 alternative_service_info_vector.push_back(
10790 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10791 alternative_service1, expiration,
10792 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2110793 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2110794 alternative_service_info_vector.push_back(
10795 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
10796 alternative_service2, expiration,
10797 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0210798
10799 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610800 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210801
10802 // Mark one of the QUIC alternative service as broken.
10803 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3410804 EXPECT_EQ(2u,
10805 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0210806
zhongyi48704c182015-12-07 07:52:0210807 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4610808 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0210809 request.method = "GET";
10810 request.url = GURL(origin_url);
zhongyi48704c182015-12-07 07:52:0210811 TestCompletionCallback callback;
10812 NetErrorDetails details;
10813 EXPECT_FALSE(details.quic_broken);
10814
tfarina42834112016-09-22 13:38:2010815 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1610816 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0210817 EXPECT_FALSE(details.quic_broken);
10818}
10819
bncd16676a2016-07-20 16:23:0110820TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4210821 HttpRequestInfo request;
10822 request.method = "GET";
bncb26024382016-06-29 02:39:4510823 request.url = GURL("https://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210824
[email protected]d973e99a2012-02-17 21:02:3610825 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210826 StaticSocketDataProvider first_data;
10827 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710828 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4510829 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610830 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510831 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4210832
10833 MockRead data_reads[] = {
10834 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10835 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610836 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210837 };
10838 StaticSocketDataProvider second_data(
10839 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710840 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210841
danakj1fd259a02016-04-16 03:17:0910842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210843
bnc525e175a2016-06-20 12:36:4010844 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310845 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610846 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110847 // Port must be < 1024, or the header will be ignored (since initial port was
10848 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2110849 // Port is ignored by MockConnect anyway.
10850 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10851 666);
bnc7dc7e1b42015-07-28 14:43:1210852 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110853 http_server_properties->SetHttp2AlternativeService(
10854 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4210855
bnc691fda62016-08-12 00:43:1610856 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110857 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210858
tfarina42834112016-09-22 13:38:2010859 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110860 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10861 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4210862
bnc691fda62016-08-12 00:43:1610863 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210864 ASSERT_TRUE(response);
10865 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210866 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10867
10868 std::string response_data;
bnc691fda62016-08-12 00:43:1610869 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4210870 EXPECT_EQ("hello world", response_data);
10871
zhongyic4de03032017-05-19 04:07:3410872 const AlternativeServiceInfoVector alternative_service_info_vector =
10873 http_server_properties->GetAlternativeServiceInfos(server);
10874 ASSERT_EQ(1u, alternative_service_info_vector.size());
10875 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5410876 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3410877 EXPECT_TRUE(
10878 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4210879}
10880
bnc55ff9da2015-08-19 18:42:3510881// Ensure that we are not allowed to redirect traffic via an alternate protocol
10882// to an unrestricted (port >= 1024) when the original traffic was on a
10883// restricted port (port < 1024). Ensure that we can redirect in all other
10884// cases.
bncd16676a2016-07-20 16:23:0110885TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1110886 HttpRequestInfo restricted_port_request;
10887 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510888 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110889 restricted_port_request.load_flags = 0;
10890
[email protected]d973e99a2012-02-17 21:02:3610891 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110892 StaticSocketDataProvider first_data;
10893 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710894 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110895
10896 MockRead data_reads[] = {
10897 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10898 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610899 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110900 };
10901 StaticSocketDataProvider second_data(
10902 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710903 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510904 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610905 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510906 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1110907
danakj1fd259a02016-04-16 03:17:0910908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110909
bnc525e175a2016-06-20 12:36:4010910 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310911 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110912 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110913 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10914 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210915 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110916 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610917 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010918 expiration);
[email protected]3912662a32011-10-04 00:51:1110919
bnc691fda62016-08-12 00:43:1610920 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110921 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110922
tfarina42834112016-09-22 13:38:2010923 int rv = trans.Start(&restricted_port_request, callback.callback(),
10924 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1110926 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0110927 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1910928}
[email protected]3912662a32011-10-04 00:51:1110929
bnc55ff9da2015-08-19 18:42:3510930// Ensure that we are allowed to redirect traffic via an alternate protocol to
10931// an unrestricted (port >= 1024) when the original traffic was on a restricted
10932// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0110933TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0710934 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910935
10936 HttpRequestInfo restricted_port_request;
10937 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510938 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910939 restricted_port_request.load_flags = 0;
10940
10941 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10942 StaticSocketDataProvider first_data;
10943 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710944 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910945
10946 MockRead data_reads[] = {
10947 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10948 MockRead("hello world"),
10949 MockRead(ASYNC, OK),
10950 };
10951 StaticSocketDataProvider second_data(
10952 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710953 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4510954 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610955 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4510956 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1910957
danakj1fd259a02016-04-16 03:17:0910958 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910959
bnc525e175a2016-06-20 12:36:4010960 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910961 session->http_server_properties();
10962 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2110963 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
10964 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210965 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110966 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610967 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010968 expiration);
[email protected]c54c6962013-02-01 04:53:1910969
bnc691fda62016-08-12 00:43:1610970 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1910971 TestCompletionCallback callback;
10972
tfarina42834112016-09-22 13:38:2010973 EXPECT_EQ(ERR_IO_PENDING,
10974 trans.Start(&restricted_port_request, callback.callback(),
10975 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1910976 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0110977 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1110978}
10979
bnc55ff9da2015-08-19 18:42:3510980// Ensure that we are not allowed to redirect traffic via an alternate protocol
10981// to an unrestricted (port >= 1024) when the original traffic was on a
10982// restricted port (port < 1024). Ensure that we can redirect in all other
10983// cases.
bncd16676a2016-07-20 16:23:0110984TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1110985 HttpRequestInfo restricted_port_request;
10986 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4510987 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110988 restricted_port_request.load_flags = 0;
10989
[email protected]d973e99a2012-02-17 21:02:3610990 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110991 StaticSocketDataProvider first_data;
10992 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710993 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110994
10995 MockRead data_reads[] = {
10996 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10997 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610998 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110999 };
11000 StaticSocketDataProvider second_data(
11001 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711002 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111003
bncb26024382016-06-29 02:39:4511004 SSLSocketDataProvider ssl(ASYNC, OK);
11005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11006
danakj1fd259a02016-04-16 03:17:0911007 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111008
bnc525e175a2016-06-20 12:36:4011009 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311010 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111011 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111012 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11013 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211014 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111015 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611016 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011017 expiration);
[email protected]3912662a32011-10-04 00:51:1111018
bnc691fda62016-08-12 00:43:1611019 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111020 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111021
tfarina42834112016-09-22 13:38:2011022 int rv = trans.Start(&restricted_port_request, callback.callback(),
11023 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111025 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111026 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111027}
11028
bnc55ff9da2015-08-19 18:42:3511029// Ensure that we are not allowed to redirect traffic via an alternate protocol
11030// to an unrestricted (port >= 1024) when the original traffic was on a
11031// restricted port (port < 1024). Ensure that we can redirect in all other
11032// cases.
bncd16676a2016-07-20 16:23:0111033TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111034 HttpRequestInfo unrestricted_port_request;
11035 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511036 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111037 unrestricted_port_request.load_flags = 0;
11038
[email protected]d973e99a2012-02-17 21:02:3611039 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111040 StaticSocketDataProvider first_data;
11041 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711042 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111043
11044 MockRead data_reads[] = {
11045 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11046 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611047 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111048 };
11049 StaticSocketDataProvider second_data(
11050 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711051 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511052 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611053 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511054 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111055
danakj1fd259a02016-04-16 03:17:0911056 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111057
bnc525e175a2016-06-20 12:36:4011058 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311059 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111060 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111061 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11062 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211063 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111064 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611065 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011066 expiration);
[email protected]3912662a32011-10-04 00:51:1111067
bnc691fda62016-08-12 00:43:1611068 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111069 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111070
bnc691fda62016-08-12 00:43:1611071 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011072 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111073 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111074 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111075 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111076}
11077
bnc55ff9da2015-08-19 18:42:3511078// Ensure that we are not allowed to redirect traffic via an alternate protocol
11079// to an unrestricted (port >= 1024) when the original traffic was on a
11080// restricted port (port < 1024). Ensure that we can redirect in all other
11081// cases.
bncd16676a2016-07-20 16:23:0111082TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111083 HttpRequestInfo unrestricted_port_request;
11084 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511085 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111086 unrestricted_port_request.load_flags = 0;
11087
[email protected]d973e99a2012-02-17 21:02:3611088 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111089 StaticSocketDataProvider first_data;
11090 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711091 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111092
11093 MockRead data_reads[] = {
11094 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11095 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611096 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111097 };
11098 StaticSocketDataProvider second_data(
11099 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711100 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111101
bncb26024382016-06-29 02:39:4511102 SSLSocketDataProvider ssl(ASYNC, OK);
11103 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11104
danakj1fd259a02016-04-16 03:17:0911105 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111106
bnc525e175a2016-06-20 12:36:4011107 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311108 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211109 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111110 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11111 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211112 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111113 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611114 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011115 expiration);
[email protected]3912662a32011-10-04 00:51:1111116
bnc691fda62016-08-12 00:43:1611117 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111118 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111119
bnc691fda62016-08-12 00:43:1611120 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011121 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111122 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111123 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111124 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111125}
11126
bnc55ff9da2015-08-19 18:42:3511127// Ensure that we are not allowed to redirect traffic via an alternate protocol
11128// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
11129// once the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111130TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211131 HttpRequestInfo request;
11132 request.method = "GET";
bncce36dca22015-04-21 22:11:2311133 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0211134
11135 // The alternate protocol request will error out before we attempt to connect,
11136 // so only the standard HTTP request will try to connect.
11137 MockRead data_reads[] = {
11138 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11139 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611140 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211141 };
11142 StaticSocketDataProvider data(
11143 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711144 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211145
danakj1fd259a02016-04-16 03:17:0911146 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211147
bnc525e175a2016-06-20 12:36:4011148 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211149 session->http_server_properties();
11150 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111151 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11152 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211153 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111154 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611155 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211156
bnc691fda62016-08-12 00:43:1611157 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211158 TestCompletionCallback callback;
11159
tfarina42834112016-09-22 13:38:2011160 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111161 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211162 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111163 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211164
bnc691fda62016-08-12 00:43:1611165 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211166 ASSERT_TRUE(response);
11167 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211168 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11169
11170 std::string response_data;
bnc691fda62016-08-12 00:43:1611171 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211172 EXPECT_EQ("hello world", response_data);
11173}
11174
bncd16676a2016-07-20 16:23:0111175TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411176 HttpRequestInfo request;
11177 request.method = "GET";
bncb26024382016-06-29 02:39:4511178 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411179
11180 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211181 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311182 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211183 MockRead("\r\n"),
11184 MockRead("hello world"),
11185 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11186 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411187
11188 StaticSocketDataProvider first_transaction(
11189 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711190 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511191 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611192 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511193 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411194
bnc032658ba2016-09-26 18:17:1511195 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411196
bncdf80d44fd2016-07-15 20:27:4111197 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511198 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111199 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411200
bnc42331402016-07-25 13:36:1511201 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111202 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411203 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111204 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411205 };
11206
rch8e6c6c42015-05-01 14:05:1311207 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11208 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711209 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411210
[email protected]d973e99a2012-02-17 21:02:3611211 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511212 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11213 NULL, 0, NULL, 0);
11214 hanging_non_alternate_protocol_socket.set_connect_data(
11215 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711216 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511217 &hanging_non_alternate_protocol_socket);
11218
[email protected]49639fa2011-12-20 23:22:4111219 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411220
danakj1fd259a02016-04-16 03:17:0911221 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811222 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911223 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411224
tfarina42834112016-09-22 13:38:2011225 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111226 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11227 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411228
11229 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211230 ASSERT_TRUE(response);
11231 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411232 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11233
11234 std::string response_data;
robpercival214763f2016-07-01 23:27:0111235 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411236 EXPECT_EQ("hello world", response_data);
11237
bnc87dcefc2017-05-25 12:47:5811238 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911239 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411240
tfarina42834112016-09-22 13:38:2011241 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111242 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11243 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411244
11245 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211246 ASSERT_TRUE(response);
11247 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211248 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311249 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211250 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411251
robpercival214763f2016-07-01 23:27:0111252 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411253 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411254}
11255
bncd16676a2016-07-20 16:23:0111256TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511257 HttpRequestInfo request;
11258 request.method = "GET";
bncb26024382016-06-29 02:39:4511259 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511260
bncb26024382016-06-29 02:39:4511261 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511262 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211263 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311264 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211265 MockRead("\r\n"),
11266 MockRead("hello world"),
11267 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11268 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511269 };
11270
bncb26024382016-06-29 02:39:4511271 StaticSocketDataProvider http11_data(data_reads, arraysize(data_reads), NULL,
11272 0);
11273 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511274
bncb26024382016-06-29 02:39:4511275 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0811276 ssl_http11.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11277 ASSERT_TRUE(ssl_http11.cert);
bncb26024382016-06-29 02:39:4511278 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11279
11280 // Second transaction starts an alternative and a non-alternative Job.
11281 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611282 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1811283 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
11284 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811285 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11286
11287 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
11288 hanging_socket2.set_connect_data(never_finishing_connect);
11289 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511290
bncb26024382016-06-29 02:39:4511291 // Third transaction starts an alternative and a non-alternative job.
11292 // The non-alternative job hangs, but the alternative one succeeds.
11293 // The second transaction, still pending, binds to this socket.
bncdf80d44fd2016-07-15 20:27:4111294 SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4511295 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111296 SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4511297 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5511298 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4111299 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5511300 };
bnc42331402016-07-25 13:36:1511301 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111302 SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1511303 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4111304 SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5511305 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111306 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
11307 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1311308 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5511309 };
11310
rch8e6c6c42015-05-01 14:05:1311311 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11312 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711313 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5511314
bnc032658ba2016-09-26 18:17:1511315 AddSSLSocketData();
bncb26024382016-06-29 02:39:4511316
mmenkecc2298e2015-12-07 18:20:1811317 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
11318 hanging_socket3.set_connect_data(never_finishing_connect);
11319 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5511320
danakj1fd259a02016-04-16 03:17:0911321 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4111322 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5011323 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511324
tfarina42834112016-09-22 13:38:2011325 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111326 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11327 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511328
11329 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211330 ASSERT_TRUE(response);
11331 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511332 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11333
11334 std::string response_data;
robpercival214763f2016-07-01 23:27:0111335 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511336 EXPECT_EQ("hello world", response_data);
11337
[email protected]49639fa2011-12-20 23:22:4111338 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011339 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011340 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111341 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511342
[email protected]49639fa2011-12-20 23:22:4111343 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011344 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2011345 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111346 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5511347
robpercival214763f2016-07-01 23:27:0111348 EXPECT_THAT(callback2.WaitForResult(), IsOk());
11349 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511350
11351 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211352 ASSERT_TRUE(response);
11353 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211354 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511355 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211356 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111357 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511358 EXPECT_EQ("hello!", response_data);
11359
11360 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211361 ASSERT_TRUE(response);
11362 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211363 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511364 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211365 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0111366 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511367 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511368}
11369
bncd16676a2016-07-20 16:23:0111370TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
[email protected]2d6728692011-03-12 01:39:5511371 HttpRequestInfo request;
11372 request.method = "GET";
bncb26024382016-06-29 02:39:4511373 request.url = GURL("https://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511374
11375 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211376 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311377 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211378 MockRead("\r\n"),
11379 MockRead("hello world"),
11380 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11381 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511382 };
11383
11384 StaticSocketDataProvider first_transaction(
11385 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711386 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511387
[email protected]8ddf8322012-02-23 18:08:0611388 SSLSocketDataProvider ssl(ASYNC, OK);
Bence Béky230ac612017-08-30 19:17:0811389 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11390 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0711391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511392
[email protected]d973e99a2012-02-17 21:02:3611393 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511394 StaticSocketDataProvider hanging_alternate_protocol_socket(
11395 NULL, 0, NULL, 0);
11396 hanging_alternate_protocol_socket.set_connect_data(
11397 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711398 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511399 &hanging_alternate_protocol_socket);
11400
bncb26024382016-06-29 02:39:4511401 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
mmenkecc2298e2015-12-07 18:20:1811402 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11403 NULL, 0);
11404 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4511405 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511406
[email protected]49639fa2011-12-20 23:22:4111407 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511408
danakj1fd259a02016-04-16 03:17:0911409 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811410 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911411 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511412
tfarina42834112016-09-22 13:38:2011413 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111414 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11415 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511416
11417 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211418 ASSERT_TRUE(response);
11419 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511420 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11421
11422 std::string response_data;
robpercival214763f2016-07-01 23:27:0111423 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511424 EXPECT_EQ("hello world", response_data);
11425
bnc87dcefc2017-05-25 12:47:5811426 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911427 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511428
tfarina42834112016-09-22 13:38:2011429 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111430 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11431 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5511432
11433 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211434 ASSERT_TRUE(response);
11435 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511436 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11437 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211438 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5511439
robpercival214763f2016-07-01 23:27:0111440 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5511441 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511442}
11443
[email protected]631f1322010-04-30 17:59:1111444class CapturingProxyResolver : public ProxyResolver {
11445 public:
sammce90c9212015-05-27 23:43:3511446 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011447 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111448
dchengb03027d2014-10-21 12:00:2011449 int GetProxyForURL(const GURL& url,
11450 ProxyInfo* results,
11451 const CompletionCallback& callback,
maksim.sisov7e157262016-10-20 11:19:5511452 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2011453 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011454 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11455 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211456 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111457 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211458 return OK;
[email protected]631f1322010-04-30 17:59:1111459 }
11460
[email protected]24476402010-07-20 20:55:1711461 const std::vector<GURL>& resolved() const { return resolved_; }
11462
11463 private:
[email protected]631f1322010-04-30 17:59:1111464 std::vector<GURL> resolved_;
11465
11466 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11467};
11468
sammce64b2362015-04-29 03:50:2311469class CapturingProxyResolverFactory : public ProxyResolverFactory {
11470 public:
11471 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11472 : ProxyResolverFactory(false), resolver_(resolver) {}
11473
11474 int CreateProxyResolver(
11475 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911476 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311477 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911478 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1911479 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2311480 return OK;
11481 }
11482
11483 private:
11484 ProxyResolver* resolver_;
11485};
11486
bnc2e884782016-08-11 19:45:1911487// Test that proxy is resolved using the origin url,
11488// regardless of the alternative server.
11489TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
11490 // Configure proxy to bypass www.example.org, which is the origin URL.
11491 ProxyConfig proxy_config;
11492 proxy_config.proxy_rules().ParseFromString("myproxy:70");
11493 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
11494 auto proxy_config_service =
Jeremy Roman0579ed62017-08-29 15:56:1911495 std::make_unique<ProxyConfigServiceFixed>(proxy_config);
bnc2e884782016-08-11 19:45:1911496
11497 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911498 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1911499 &capturing_proxy_resolver);
11500
11501 TestNetLog net_log;
11502
Jeremy Roman0579ed62017-08-29 15:56:1911503 session_deps_.proxy_service = std::make_unique<ProxyService>(
bnc2e884782016-08-11 19:45:1911504 std::move(proxy_config_service), std::move(proxy_resolver_factory),
11505 &net_log);
11506
11507 session_deps_.net_log = &net_log;
11508
11509 // Configure alternative service with a hostname that is not bypassed by the
11510 // proxy.
11511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11512 HttpServerProperties* http_server_properties =
11513 session->http_server_properties();
11514 url::SchemeHostPort server("https", "www.example.org", 443);
11515 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2111516 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1911517 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111518 http_server_properties->SetHttp2AlternativeService(
11519 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1911520
11521 // Non-alternative job should hang.
11522 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
11523 StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0,
11524 nullptr, 0);
11525 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
11526 session_deps_.socket_factory->AddSocketDataProvider(
11527 &hanging_alternate_protocol_socket);
11528
bnc032658ba2016-09-26 18:17:1511529 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1911530
11531 HttpRequestInfo request;
11532 request.method = "GET";
11533 request.url = GURL("https://www.example.org/");
11534 request.load_flags = 0;
11535
11536 SpdySerializedFrame req(
11537 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
11538
11539 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
11540
11541 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
11542 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
11543 MockRead spdy_reads[] = {
11544 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
11545 };
11546
11547 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11548 arraysize(spdy_writes));
11549 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
11550
11551 TestCompletionCallback callback;
11552
11553 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11554
tfarina42834112016-09-22 13:38:2011555 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1911556 EXPECT_THAT(callback.GetResult(rv), IsOk());
11557
11558 const HttpResponseInfo* response = trans.GetResponseInfo();
11559 ASSERT_TRUE(response);
11560 ASSERT_TRUE(response->headers);
11561 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
11562 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211563 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1911564
11565 std::string response_data;
11566 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11567 EXPECT_EQ("hello!", response_data);
11568
11569 // Origin host bypasses proxy, no resolution should have happened.
11570 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
11571}
11572
bncd16676a2016-07-20 16:23:0111573TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1111574 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211575 proxy_config.set_auto_detect(true);
11576 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111577
sammc5dd160c2015-04-02 02:43:1311578 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1911579 session_deps_.proxy_service = std::make_unique<ProxyService>(
11580 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
11581 std::make_unique<CapturingProxyResolverFactory>(
bnc87dcefc2017-05-25 12:47:5811582 &capturing_proxy_resolver),
11583 nullptr);
vishal.b62985ca92015-04-17 08:45:5111584 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711585 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111586
11587 HttpRequestInfo request;
11588 request.method = "GET";
bncb26024382016-06-29 02:39:4511589 request.url = GURL("https://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111590
11591 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211592 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311593 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211594 MockRead("\r\n"),
11595 MockRead("hello world"),
11596 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11597 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111598 };
11599
11600 StaticSocketDataProvider first_transaction(
11601 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711602 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511603 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611604 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511605 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1111606
bnc032658ba2016-09-26 18:17:1511607 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1111608
bncdf80d44fd2016-07-15 20:27:4111609 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511610 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1111611 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311612 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511613 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11614 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311615 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4111616 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1111617 };
11618
[email protected]d911f1b2010-05-05 22:39:4211619 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11620
bnc42331402016-07-25 13:36:1511621 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111622 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111623 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111624 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
11625 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111626 };
11627
rch8e6c6c42015-05-01 14:05:1311628 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11629 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711630 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111631
[email protected]d973e99a2012-02-17 21:02:3611632 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511633 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11634 NULL, 0, NULL, 0);
11635 hanging_non_alternate_protocol_socket.set_connect_data(
11636 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711637 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511638 &hanging_non_alternate_protocol_socket);
11639
[email protected]49639fa2011-12-20 23:22:4111640 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111641
danakj1fd259a02016-04-16 03:17:0911642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811643 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911644 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111645
tfarina42834112016-09-22 13:38:2011646 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4111647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11648 EXPECT_THAT(callback.WaitForResult(), IsOk());
11649
11650 const HttpResponseInfo* response = trans->GetResponseInfo();
11651 ASSERT_TRUE(response);
11652 ASSERT_TRUE(response->headers);
11653 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
11654 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211655 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4111656
11657 std::string response_data;
11658 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
11659 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1111660
bnc87dcefc2017-05-25 12:47:5811661 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911662 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1111663
tfarina42834112016-09-22 13:38:2011664 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11666 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1111667
mmenkea2dcd3bf2016-08-16 21:49:4111668 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211669 ASSERT_TRUE(response);
11670 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211671 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311672 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211673 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1111674
robpercival214763f2016-07-01 23:27:0111675 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1111676 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4511677 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
11678 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311679 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311680 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311681 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111682
[email protected]029c83b62013-01-24 05:28:2011683 LoadTimingInfo load_timing_info;
11684 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11685 TestLoadTimingNotReusedWithPac(load_timing_info,
11686 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111687}
[email protected]631f1322010-04-30 17:59:1111688
bncd16676a2016-07-20 16:23:0111689TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811690 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5411691 HttpRequestInfo request;
11692 request.method = "GET";
bncb26024382016-06-29 02:39:4511693 request.url = GURL("https://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411694
11695 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211696 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311697 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211698 MockRead("\r\n"),
11699 MockRead("hello world"),
11700 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411701 };
11702
11703 StaticSocketDataProvider first_transaction(
11704 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711705 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511706 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611707 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511708 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411709
bnc032658ba2016-09-26 18:17:1511710 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411711
bncdf80d44fd2016-07-15 20:27:4111712 SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511713 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111714 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411715
bnc42331402016-07-25 13:36:1511716 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4111717 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411718 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111719 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411720 };
11721
rch8e6c6c42015-05-01 14:05:1311722 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11723 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711724 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411725
[email protected]83039bb2011-12-09 18:43:5511726 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411727
danakj1fd259a02016-04-16 03:17:0911728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411729
bnc87dcefc2017-05-25 12:47:5811730 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911731 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411732
tfarina42834112016-09-22 13:38:2011733 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111734 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11735 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411736
11737 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211738 ASSERT_TRUE(response);
11739 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411740 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11741
11742 std::string response_data;
robpercival214763f2016-07-01 23:27:0111743 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411744 EXPECT_EQ("hello world", response_data);
11745
11746 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511747 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011748 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311749 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711750 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5211751 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3811752
bnc87dcefc2017-05-25 12:47:5811753 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911754 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411755
tfarina42834112016-09-22 13:38:2011756 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111757 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11758 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411759
11760 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211761 ASSERT_TRUE(response);
11762 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211763 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311764 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211765 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411766
robpercival214763f2016-07-01 23:27:0111767 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411768 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211769}
11770
[email protected]044de0642010-06-17 10:42:1511771// GenerateAuthToken is a mighty big test.
11772// It tests all permutation of GenerateAuthToken behavior:
11773// - Synchronous and Asynchronous completion.
11774// - OK or error on completion.
11775// - Direct connection, non-authenticating proxy, and authenticating proxy.
11776// - HTTP or HTTPS backend (to include proxy tunneling).
11777// - Non-authenticating and authenticating backend.
11778//
[email protected]fe3b7dc2012-02-03 19:52:0911779// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511780// problems generating an auth token for an authenticating proxy, we don't
11781// need to test all permutations of the backend server).
11782//
11783// The test proceeds by going over each of the configuration cases, and
11784// potentially running up to three rounds in each of the tests. The TestConfig
11785// specifies both the configuration for the test as well as the expectations
11786// for the results.
bncd16676a2016-07-20 16:23:0111787TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011788 static const char kServer[] = "http://www.example.com";
11789 static const char kSecureServer[] = "https://www.example.com";
11790 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511791
11792 enum AuthTiming {
11793 AUTH_NONE,
11794 AUTH_SYNC,
11795 AUTH_ASYNC,
11796 };
11797
11798 const MockWrite kGet(
11799 "GET / HTTP/1.1\r\n"
11800 "Host: www.example.com\r\n"
11801 "Connection: keep-alive\r\n\r\n");
11802 const MockWrite kGetProxy(
11803 "GET http://www.example.com/ HTTP/1.1\r\n"
11804 "Host: www.example.com\r\n"
11805 "Proxy-Connection: keep-alive\r\n\r\n");
11806 const MockWrite kGetAuth(
11807 "GET / HTTP/1.1\r\n"
11808 "Host: www.example.com\r\n"
11809 "Connection: keep-alive\r\n"
11810 "Authorization: auth_token\r\n\r\n");
11811 const MockWrite kGetProxyAuth(
11812 "GET http://www.example.com/ HTTP/1.1\r\n"
11813 "Host: www.example.com\r\n"
11814 "Proxy-Connection: keep-alive\r\n"
11815 "Proxy-Authorization: auth_token\r\n\r\n");
11816 const MockWrite kGetAuthThroughProxy(
11817 "GET http://www.example.com/ HTTP/1.1\r\n"
11818 "Host: www.example.com\r\n"
11819 "Proxy-Connection: keep-alive\r\n"
11820 "Authorization: auth_token\r\n\r\n");
11821 const MockWrite kGetAuthWithProxyAuth(
11822 "GET http://www.example.com/ HTTP/1.1\r\n"
11823 "Host: www.example.com\r\n"
11824 "Proxy-Connection: keep-alive\r\n"
11825 "Proxy-Authorization: auth_token\r\n"
11826 "Authorization: auth_token\r\n\r\n");
11827 const MockWrite kConnect(
11828 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711829 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511830 "Proxy-Connection: keep-alive\r\n\r\n");
11831 const MockWrite kConnectProxyAuth(
11832 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711833 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511834 "Proxy-Connection: keep-alive\r\n"
11835 "Proxy-Authorization: auth_token\r\n\r\n");
11836
11837 const MockRead kSuccess(
11838 "HTTP/1.1 200 OK\r\n"
11839 "Content-Type: text/html; charset=iso-8859-1\r\n"
11840 "Content-Length: 3\r\n\r\n"
11841 "Yes");
11842 const MockRead kFailure(
11843 "Should not be called.");
11844 const MockRead kServerChallenge(
11845 "HTTP/1.1 401 Unauthorized\r\n"
11846 "WWW-Authenticate: Mock realm=server\r\n"
11847 "Content-Type: text/html; charset=iso-8859-1\r\n"
11848 "Content-Length: 14\r\n\r\n"
11849 "Unauthorized\r\n");
11850 const MockRead kProxyChallenge(
11851 "HTTP/1.1 407 Unauthorized\r\n"
11852 "Proxy-Authenticate: Mock realm=proxy\r\n"
11853 "Proxy-Connection: close\r\n"
11854 "Content-Type: text/html; charset=iso-8859-1\r\n"
11855 "Content-Length: 14\r\n\r\n"
11856 "Unauthorized\r\n");
11857 const MockRead kProxyConnected(
11858 "HTTP/1.1 200 Connection Established\r\n\r\n");
11859
11860 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11861 // no constructors, but the C++ compiler on Windows warns about
11862 // unspecified data in compound literals. So, moved to using constructors,
11863 // and TestRound's created with the default constructor should not be used.
11864 struct TestRound {
11865 TestRound()
11866 : expected_rv(ERR_UNEXPECTED),
11867 extra_write(NULL),
11868 extra_read(NULL) {
11869 }
11870 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11871 int expected_rv_arg)
11872 : write(write_arg),
11873 read(read_arg),
11874 expected_rv(expected_rv_arg),
11875 extra_write(NULL),
11876 extra_read(NULL) {
11877 }
11878 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11879 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111880 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511881 : write(write_arg),
11882 read(read_arg),
11883 expected_rv(expected_rv_arg),
11884 extra_write(extra_write_arg),
11885 extra_read(extra_read_arg) {
11886 }
11887 MockWrite write;
11888 MockRead read;
11889 int expected_rv;
11890 const MockWrite* extra_write;
11891 const MockRead* extra_read;
11892 };
11893
11894 static const int kNoSSL = 500;
11895
11896 struct TestConfig {
asanka463ca4262016-11-16 02:34:3111897 int line_number;
thestig9d3bb0c2015-01-24 00:49:5111898 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511899 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3111900 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5111901 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511902 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3111903 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1511904 int num_auth_rounds;
11905 int first_ssl_round;
asankae2257db2016-10-11 22:03:1611906 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1511907 } test_configs[] = {
asankac93076192016-10-03 15:46:0211908 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111909 {__LINE__,
11910 nullptr,
asankac93076192016-10-03 15:46:0211911 AUTH_NONE,
11912 OK,
11913 kServer,
11914 AUTH_NONE,
11915 OK,
11916 1,
11917 kNoSSL,
11918 {TestRound(kGet, kSuccess, OK)}},
11919 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3111920 {__LINE__,
11921 nullptr,
asankac93076192016-10-03 15:46:0211922 AUTH_NONE,
11923 OK,
11924 kServer,
11925 AUTH_SYNC,
11926 OK,
11927 2,
11928 kNoSSL,
11929 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1511930 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111931 {__LINE__,
11932 nullptr,
asankac93076192016-10-03 15:46:0211933 AUTH_NONE,
11934 OK,
11935 kServer,
11936 AUTH_SYNC,
11937 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1611938 3,
11939 kNoSSL,
11940 {TestRound(kGet, kServerChallenge, OK),
11941 TestRound(kGet, kServerChallenge, OK),
11942 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111943 {__LINE__,
11944 nullptr,
asankae2257db2016-10-11 22:03:1611945 AUTH_NONE,
11946 OK,
11947 kServer,
11948 AUTH_SYNC,
11949 ERR_UNSUPPORTED_AUTH_SCHEME,
11950 2,
11951 kNoSSL,
11952 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111953 {__LINE__,
11954 nullptr,
asankae2257db2016-10-11 22:03:1611955 AUTH_NONE,
11956 OK,
11957 kServer,
11958 AUTH_SYNC,
11959 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
11960 2,
11961 kNoSSL,
11962 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3111963 {__LINE__,
11964 kProxy,
asankae2257db2016-10-11 22:03:1611965 AUTH_SYNC,
11966 ERR_FAILED,
11967 kServer,
11968 AUTH_NONE,
11969 OK,
11970 2,
11971 kNoSSL,
11972 {TestRound(kGetProxy, kProxyChallenge, OK),
11973 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111974 {__LINE__,
11975 kProxy,
asankae2257db2016-10-11 22:03:1611976 AUTH_ASYNC,
11977 ERR_FAILED,
11978 kServer,
11979 AUTH_NONE,
11980 OK,
11981 2,
11982 kNoSSL,
11983 {TestRound(kGetProxy, kProxyChallenge, OK),
11984 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111985 {__LINE__,
11986 nullptr,
asankae2257db2016-10-11 22:03:1611987 AUTH_NONE,
11988 OK,
11989 kServer,
11990 AUTH_SYNC,
11991 ERR_FAILED,
asankac93076192016-10-03 15:46:0211992 2,
11993 kNoSSL,
11994 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1611995 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3111996 {__LINE__,
11997 nullptr,
asankae2257db2016-10-11 22:03:1611998 AUTH_NONE,
11999 OK,
12000 kServer,
12001 AUTH_ASYNC,
12002 ERR_FAILED,
12003 2,
12004 kNoSSL,
12005 {TestRound(kGet, kServerChallenge, OK),
12006 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112007 {__LINE__,
12008 nullptr,
asankac93076192016-10-03 15:46:0212009 AUTH_NONE,
12010 OK,
12011 kServer,
12012 AUTH_ASYNC,
12013 OK,
12014 2,
12015 kNoSSL,
12016 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512017 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112018 {__LINE__,
12019 nullptr,
asankac93076192016-10-03 15:46:0212020 AUTH_NONE,
12021 OK,
12022 kServer,
12023 AUTH_ASYNC,
12024 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612025 3,
asankac93076192016-10-03 15:46:0212026 kNoSSL,
12027 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612028 // The second round uses a HttpAuthHandlerMock that always succeeds.
12029 TestRound(kGet, kServerChallenge, OK),
12030 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212031 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112032 {__LINE__,
12033 kProxy,
asankac93076192016-10-03 15:46:0212034 AUTH_NONE,
12035 OK,
12036 kServer,
12037 AUTH_NONE,
12038 OK,
12039 1,
12040 kNoSSL,
12041 {TestRound(kGetProxy, kSuccess, OK)}},
12042 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112043 {__LINE__,
12044 kProxy,
asankac93076192016-10-03 15:46:0212045 AUTH_NONE,
12046 OK,
12047 kServer,
12048 AUTH_SYNC,
12049 OK,
12050 2,
12051 kNoSSL,
12052 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512053 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112054 {__LINE__,
12055 kProxy,
asankac93076192016-10-03 15:46:0212056 AUTH_NONE,
12057 OK,
12058 kServer,
12059 AUTH_SYNC,
12060 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612061 3,
asankac93076192016-10-03 15:46:0212062 kNoSSL,
12063 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612064 TestRound(kGetProxy, kServerChallenge, OK),
12065 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112066 {__LINE__,
12067 kProxy,
asankac93076192016-10-03 15:46:0212068 AUTH_NONE,
12069 OK,
12070 kServer,
12071 AUTH_ASYNC,
12072 OK,
12073 2,
12074 kNoSSL,
12075 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512076 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112077 {__LINE__,
12078 kProxy,
asankac93076192016-10-03 15:46:0212079 AUTH_NONE,
12080 OK,
12081 kServer,
12082 AUTH_ASYNC,
12083 ERR_INVALID_AUTH_CREDENTIALS,
12084 2,
12085 kNoSSL,
12086 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612087 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212088 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112089 {__LINE__,
12090 kProxy,
asankac93076192016-10-03 15:46:0212091 AUTH_SYNC,
12092 OK,
12093 kServer,
12094 AUTH_NONE,
12095 OK,
12096 2,
12097 kNoSSL,
12098 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512099 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112100 {__LINE__,
12101 kProxy,
asankac93076192016-10-03 15:46:0212102 AUTH_SYNC,
12103 ERR_INVALID_AUTH_CREDENTIALS,
12104 kServer,
12105 AUTH_NONE,
12106 OK,
12107 2,
12108 kNoSSL,
12109 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612110 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112111 {__LINE__,
12112 kProxy,
asankac93076192016-10-03 15:46:0212113 AUTH_ASYNC,
12114 OK,
12115 kServer,
12116 AUTH_NONE,
12117 OK,
12118 2,
12119 kNoSSL,
12120 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512121 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112122 {__LINE__,
12123 kProxy,
asankac93076192016-10-03 15:46:0212124 AUTH_ASYNC,
12125 ERR_INVALID_AUTH_CREDENTIALS,
12126 kServer,
12127 AUTH_NONE,
12128 OK,
12129 2,
12130 kNoSSL,
12131 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612132 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112133 {__LINE__,
12134 kProxy,
12135 AUTH_ASYNC,
12136 ERR_INVALID_AUTH_CREDENTIALS,
12137 kServer,
12138 AUTH_NONE,
12139 OK,
12140 3,
12141 kNoSSL,
12142 {TestRound(kGetProxy, kProxyChallenge, OK),
12143 TestRound(kGetProxy, kProxyChallenge, OK),
12144 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212145 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112146 {__LINE__,
12147 kProxy,
asankac93076192016-10-03 15:46:0212148 AUTH_SYNC,
12149 OK,
12150 kServer,
12151 AUTH_SYNC,
12152 OK,
12153 3,
12154 kNoSSL,
12155 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512156 TestRound(kGetProxyAuth, kServerChallenge, OK),
12157 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112158 {__LINE__,
12159 kProxy,
asankac93076192016-10-03 15:46:0212160 AUTH_SYNC,
12161 OK,
12162 kServer,
12163 AUTH_SYNC,
12164 ERR_INVALID_AUTH_CREDENTIALS,
12165 3,
12166 kNoSSL,
12167 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512168 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612169 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112170 {__LINE__,
12171 kProxy,
asankac93076192016-10-03 15:46:0212172 AUTH_ASYNC,
12173 OK,
12174 kServer,
12175 AUTH_SYNC,
12176 OK,
12177 3,
12178 kNoSSL,
12179 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512180 TestRound(kGetProxyAuth, kServerChallenge, OK),
12181 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112182 {__LINE__,
12183 kProxy,
asankac93076192016-10-03 15:46:0212184 AUTH_ASYNC,
12185 OK,
12186 kServer,
12187 AUTH_SYNC,
12188 ERR_INVALID_AUTH_CREDENTIALS,
12189 3,
12190 kNoSSL,
12191 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512192 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612193 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112194 {__LINE__,
12195 kProxy,
asankac93076192016-10-03 15:46:0212196 AUTH_SYNC,
12197 OK,
12198 kServer,
12199 AUTH_ASYNC,
12200 OK,
12201 3,
12202 kNoSSL,
12203 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512204 TestRound(kGetProxyAuth, kServerChallenge, OK),
12205 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112206 {__LINE__,
12207 kProxy,
12208 AUTH_SYNC,
12209 ERR_INVALID_AUTH_CREDENTIALS,
12210 kServer,
12211 AUTH_ASYNC,
12212 OK,
12213 4,
12214 kNoSSL,
12215 {TestRound(kGetProxy, kProxyChallenge, OK),
12216 TestRound(kGetProxy, kProxyChallenge, OK),
12217 TestRound(kGetProxyAuth, kServerChallenge, OK),
12218 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12219 {__LINE__,
12220 kProxy,
asankac93076192016-10-03 15:46:0212221 AUTH_SYNC,
12222 OK,
12223 kServer,
12224 AUTH_ASYNC,
12225 ERR_INVALID_AUTH_CREDENTIALS,
12226 3,
12227 kNoSSL,
12228 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512229 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612230 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112231 {__LINE__,
12232 kProxy,
asankac93076192016-10-03 15:46:0212233 AUTH_ASYNC,
12234 OK,
12235 kServer,
12236 AUTH_ASYNC,
12237 OK,
12238 3,
12239 kNoSSL,
12240 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512241 TestRound(kGetProxyAuth, kServerChallenge, OK),
12242 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112243 {__LINE__,
12244 kProxy,
asankac93076192016-10-03 15:46:0212245 AUTH_ASYNC,
12246 OK,
12247 kServer,
12248 AUTH_ASYNC,
12249 ERR_INVALID_AUTH_CREDENTIALS,
12250 3,
12251 kNoSSL,
12252 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512253 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612254 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112255 {__LINE__,
12256 kProxy,
12257 AUTH_ASYNC,
12258 ERR_INVALID_AUTH_CREDENTIALS,
12259 kServer,
12260 AUTH_ASYNC,
12261 ERR_INVALID_AUTH_CREDENTIALS,
12262 4,
12263 kNoSSL,
12264 {TestRound(kGetProxy, kProxyChallenge, OK),
12265 TestRound(kGetProxy, kProxyChallenge, OK),
12266 TestRound(kGetProxyAuth, kServerChallenge, OK),
12267 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212268 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112269 {__LINE__,
12270 nullptr,
asankac93076192016-10-03 15:46:0212271 AUTH_NONE,
12272 OK,
12273 kSecureServer,
12274 AUTH_NONE,
12275 OK,
12276 1,
12277 0,
12278 {TestRound(kGet, kSuccess, OK)}},
12279 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112280 {__LINE__,
12281 nullptr,
asankac93076192016-10-03 15:46:0212282 AUTH_NONE,
12283 OK,
12284 kSecureServer,
12285 AUTH_SYNC,
12286 OK,
12287 2,
12288 0,
12289 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512290 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112291 {__LINE__,
12292 nullptr,
asankac93076192016-10-03 15:46:0212293 AUTH_NONE,
12294 OK,
12295 kSecureServer,
12296 AUTH_SYNC,
12297 ERR_INVALID_AUTH_CREDENTIALS,
12298 2,
12299 0,
asankae2257db2016-10-11 22:03:1612300 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112301 {__LINE__,
12302 nullptr,
asankac93076192016-10-03 15:46:0212303 AUTH_NONE,
12304 OK,
12305 kSecureServer,
12306 AUTH_ASYNC,
12307 OK,
12308 2,
12309 0,
12310 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512311 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112312 {__LINE__,
12313 nullptr,
asankac93076192016-10-03 15:46:0212314 AUTH_NONE,
12315 OK,
12316 kSecureServer,
12317 AUTH_ASYNC,
12318 ERR_INVALID_AUTH_CREDENTIALS,
12319 2,
12320 0,
asankae2257db2016-10-11 22:03:1612321 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212322 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112323 {__LINE__,
12324 kProxy,
asankac93076192016-10-03 15:46:0212325 AUTH_NONE,
12326 OK,
12327 kSecureServer,
12328 AUTH_NONE,
12329 OK,
12330 1,
12331 0,
12332 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
12333 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112334 {__LINE__,
12335 kProxy,
asankac93076192016-10-03 15:46:0212336 AUTH_NONE,
12337 OK,
12338 kSecureServer,
12339 AUTH_SYNC,
12340 OK,
12341 2,
12342 0,
12343 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512344 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112345 {__LINE__,
12346 kProxy,
asankac93076192016-10-03 15:46:0212347 AUTH_NONE,
12348 OK,
12349 kSecureServer,
12350 AUTH_SYNC,
12351 ERR_INVALID_AUTH_CREDENTIALS,
12352 2,
12353 0,
12354 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612355 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112356 {__LINE__,
12357 kProxy,
asankac93076192016-10-03 15:46:0212358 AUTH_NONE,
12359 OK,
12360 kSecureServer,
12361 AUTH_ASYNC,
12362 OK,
12363 2,
12364 0,
12365 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512366 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112367 {__LINE__,
12368 kProxy,
asankac93076192016-10-03 15:46:0212369 AUTH_NONE,
12370 OK,
12371 kSecureServer,
12372 AUTH_ASYNC,
12373 ERR_INVALID_AUTH_CREDENTIALS,
12374 2,
12375 0,
12376 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1612377 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212378 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112379 {__LINE__,
12380 kProxy,
asankac93076192016-10-03 15:46:0212381 AUTH_SYNC,
12382 OK,
12383 kSecureServer,
12384 AUTH_NONE,
12385 OK,
12386 2,
12387 1,
12388 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512389 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112390 {__LINE__,
12391 kProxy,
asankac93076192016-10-03 15:46:0212392 AUTH_SYNC,
12393 ERR_INVALID_AUTH_CREDENTIALS,
12394 kSecureServer,
12395 AUTH_NONE,
12396 OK,
12397 2,
12398 kNoSSL,
12399 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612400 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112401 {__LINE__,
12402 kProxy,
asankae2257db2016-10-11 22:03:1612403 AUTH_SYNC,
12404 ERR_UNSUPPORTED_AUTH_SCHEME,
12405 kSecureServer,
12406 AUTH_NONE,
12407 OK,
12408 2,
12409 kNoSSL,
12410 {TestRound(kConnect, kProxyChallenge, OK),
12411 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112412 {__LINE__,
12413 kProxy,
asankae2257db2016-10-11 22:03:1612414 AUTH_SYNC,
12415 ERR_UNEXPECTED,
12416 kSecureServer,
12417 AUTH_NONE,
12418 OK,
12419 2,
12420 kNoSSL,
12421 {TestRound(kConnect, kProxyChallenge, OK),
12422 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3112423 {__LINE__,
12424 kProxy,
asankac93076192016-10-03 15:46:0212425 AUTH_ASYNC,
12426 OK,
12427 kSecureServer,
12428 AUTH_NONE,
12429 OK,
12430 2,
12431 1,
12432 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512433 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3112434 {__LINE__,
12435 kProxy,
asankac93076192016-10-03 15:46:0212436 AUTH_ASYNC,
12437 ERR_INVALID_AUTH_CREDENTIALS,
12438 kSecureServer,
12439 AUTH_NONE,
12440 OK,
12441 2,
12442 kNoSSL,
12443 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612444 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0212445 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112446 {__LINE__,
12447 kProxy,
asankac93076192016-10-03 15:46:0212448 AUTH_SYNC,
12449 OK,
12450 kSecureServer,
12451 AUTH_SYNC,
12452 OK,
12453 3,
12454 1,
12455 {TestRound(kConnect, kProxyChallenge, OK),
12456 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12457 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512458 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112459 {__LINE__,
12460 kProxy,
asankac93076192016-10-03 15:46:0212461 AUTH_SYNC,
12462 OK,
12463 kSecureServer,
12464 AUTH_SYNC,
12465 ERR_INVALID_AUTH_CREDENTIALS,
12466 3,
12467 1,
12468 {TestRound(kConnect, kProxyChallenge, OK),
12469 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12470 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612471 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112472 {__LINE__,
12473 kProxy,
asankac93076192016-10-03 15:46:0212474 AUTH_ASYNC,
12475 OK,
12476 kSecureServer,
12477 AUTH_SYNC,
12478 OK,
12479 3,
12480 1,
12481 {TestRound(kConnect, kProxyChallenge, OK),
12482 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12483 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512484 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112485 {__LINE__,
12486 kProxy,
asankac93076192016-10-03 15:46:0212487 AUTH_ASYNC,
12488 OK,
12489 kSecureServer,
12490 AUTH_SYNC,
12491 ERR_INVALID_AUTH_CREDENTIALS,
12492 3,
12493 1,
12494 {TestRound(kConnect, kProxyChallenge, OK),
12495 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12496 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612497 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112498 {__LINE__,
12499 kProxy,
asankac93076192016-10-03 15:46:0212500 AUTH_SYNC,
12501 OK,
12502 kSecureServer,
12503 AUTH_ASYNC,
12504 OK,
12505 3,
12506 1,
12507 {TestRound(kConnect, kProxyChallenge, OK),
12508 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12509 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512510 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112511 {__LINE__,
12512 kProxy,
asankac93076192016-10-03 15:46:0212513 AUTH_SYNC,
12514 OK,
12515 kSecureServer,
12516 AUTH_ASYNC,
12517 ERR_INVALID_AUTH_CREDENTIALS,
12518 3,
12519 1,
12520 {TestRound(kConnect, kProxyChallenge, OK),
12521 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12522 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612523 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112524 {__LINE__,
12525 kProxy,
asankac93076192016-10-03 15:46:0212526 AUTH_ASYNC,
12527 OK,
12528 kSecureServer,
12529 AUTH_ASYNC,
12530 OK,
12531 3,
12532 1,
12533 {TestRound(kConnect, kProxyChallenge, OK),
12534 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12535 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1512536 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112537 {__LINE__,
12538 kProxy,
asankac93076192016-10-03 15:46:0212539 AUTH_ASYNC,
12540 OK,
12541 kSecureServer,
12542 AUTH_ASYNC,
12543 ERR_INVALID_AUTH_CREDENTIALS,
12544 3,
12545 1,
12546 {TestRound(kConnect, kProxyChallenge, OK),
12547 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12548 &kServerChallenge),
asankae2257db2016-10-11 22:03:1612549 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112550 {__LINE__,
12551 kProxy,
12552 AUTH_ASYNC,
12553 ERR_INVALID_AUTH_CREDENTIALS,
12554 kSecureServer,
12555 AUTH_ASYNC,
12556 ERR_INVALID_AUTH_CREDENTIALS,
12557 4,
12558 2,
12559 {TestRound(kConnect, kProxyChallenge, OK),
12560 TestRound(kConnect, kProxyChallenge, OK),
12561 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
12562 &kServerChallenge),
12563 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1512564 };
12565
asanka463ca4262016-11-16 02:34:3112566 for (const auto& test_config : test_configs) {
12567 SCOPED_TRACE(::testing::Message() << "Test config at "
12568 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0812569 HttpAuthHandlerMock::Factory* auth_factory(
12570 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712571 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4912572 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2612573
12574 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1512575 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3112576 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0812577 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12578 std::string auth_challenge = "Mock realm=proxy";
12579 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2412580 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12581 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0812582 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2012583 empty_ssl_info, origin,
12584 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812585 auth_handler->SetGenerateExpectation(
12586 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112587 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0812588 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12589 }
[email protected]044de0642010-06-17 10:42:1512590 }
12591 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0012592 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1512593 std::string auth_challenge = "Mock realm=server";
12594 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2412595 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12596 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1512597 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012598 empty_ssl_info, origin,
12599 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512600 auth_handler->SetGenerateExpectation(
12601 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3112602 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0812603 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1612604
12605 // The second handler always succeeds. It should only be used where there
12606 // are multiple auth sessions for server auth in the same network
12607 // transaction using the same auth scheme.
12608 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1912609 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1612610 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
12611 empty_ssl_info, origin,
12612 NetLogWithSource());
12613 second_handler->SetGenerateExpectation(true, OK);
12614 auth_factory->AddMockHandler(second_handler.release(),
12615 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1512616 }
12617 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0312618 session_deps_.proxy_service =
12619 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1512620 } else {
rdsmith82957ad2015-09-16 19:42:0312621 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1512622 }
12623
12624 HttpRequestInfo request;
12625 request.method = "GET";
12626 request.url = GURL(test_config.server_url);
[email protected]044de0642010-06-17 10:42:1512627
danakj1fd259a02016-04-16 03:17:0912628 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1512629
rchcb68dc62015-05-21 04:45:3612630 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
12631
12632 std::vector<std::vector<MockRead>> mock_reads(1);
12633 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1512634 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212635 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1512636 const TestRound& read_write_round = test_config.rounds[round];
12637
12638 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3612639 mock_reads.back().push_back(read_write_round.read);
12640 mock_writes.back().push_back(read_write_round.write);
12641
12642 // kProxyChallenge uses Proxy-Connection: close which means that the
12643 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5412644 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3612645 mock_reads.push_back(std::vector<MockRead>());
12646 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1512647 }
12648
rchcb68dc62015-05-21 04:45:3612649 if (read_write_round.extra_read) {
12650 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1512651 }
rchcb68dc62015-05-21 04:45:3612652 if (read_write_round.extra_write) {
12653 mock_writes.back().push_back(*read_write_round.extra_write);
12654 }
[email protected]044de0642010-06-17 10:42:1512655
12656 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1512657 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0712658 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1512659 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3612660 }
[email protected]044de0642010-06-17 10:42:1512661
danakj1fd259a02016-04-16 03:17:0912662 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3612663 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1912664 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
davidben5f8b6bc2015-11-25 03:19:5412665 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
bnc87dcefc2017-05-25 12:47:5812666 mock_writes[i].size()));
rchcb68dc62015-05-21 04:45:3612667 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3212668 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3612669 }
12670
mmenkecc2298e2015-12-07 18:20:1812671 // Transaction must be created after DataProviders, so it's destroyed before
12672 // they are as well.
12673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12674
rchcb68dc62015-05-21 04:45:3612675 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2212676 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3612677 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1512678 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4112679 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1512680 int rv;
12681 if (round == 0) {
tfarina42834112016-09-22 13:38:2012682 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1512683 } else {
[email protected]49639fa2011-12-20 23:22:4112684 rv = trans.RestartWithAuth(
12685 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1512686 }
12687 if (rv == ERR_IO_PENDING)
12688 rv = callback.WaitForResult();
12689
12690 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1612691 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5012692 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5512693 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1512694 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
12695 continue;
12696 }
12697 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5212698 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1512699 } else {
wezca1070932016-05-26 20:30:5212700 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1612701 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1512702 }
12703 }
[email protected]e5ae96a2010-04-14 20:12:4512704 }
12705}
12706
bncd16676a2016-07-20 16:23:0112707TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1412708 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1412709 HttpAuthHandlerMock::Factory* auth_factory(
12710 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0712711 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0312712 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0712713 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
12714 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1412715
12716 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
12717 auth_handler->set_connection_based(true);
12718 std::string auth_challenge = "Mock realm=server";
12719 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2412720 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
12721 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4912722 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1412723 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2012724 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0812725 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1412726
[email protected]c871bce92010-07-15 21:51:1412727 int rv = OK;
12728 const HttpResponseInfo* response = NULL;
12729 HttpRequestInfo request;
12730 request.method = "GET";
12731 request.url = origin;
[email protected]cb9bf6ca2011-01-28 13:15:2712732
danakj1fd259a02016-04-16 03:17:0912733 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1012734
12735 // Use a TCP Socket Pool with only one connection per group. This is used
12736 // to validate that the TCP socket is not released to the pool between
12737 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4212738 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2812739 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1012740 50, // Max sockets for pool
12741 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2112742 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
12743 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1912744 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0212745 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4812746 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1012747
bnc691fda62016-08-12 00:43:1612748 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112749 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1412750
12751 const MockWrite kGet(
12752 "GET / HTTP/1.1\r\n"
12753 "Host: www.example.com\r\n"
12754 "Connection: keep-alive\r\n\r\n");
12755 const MockWrite kGetAuth(
12756 "GET / HTTP/1.1\r\n"
12757 "Host: www.example.com\r\n"
12758 "Connection: keep-alive\r\n"
12759 "Authorization: auth_token\r\n\r\n");
12760
12761 const MockRead kServerChallenge(
12762 "HTTP/1.1 401 Unauthorized\r\n"
12763 "WWW-Authenticate: Mock realm=server\r\n"
12764 "Content-Type: text/html; charset=iso-8859-1\r\n"
12765 "Content-Length: 14\r\n\r\n"
12766 "Unauthorized\r\n");
12767 const MockRead kSuccess(
12768 "HTTP/1.1 200 OK\r\n"
12769 "Content-Type: text/html; charset=iso-8859-1\r\n"
12770 "Content-Length: 3\r\n\r\n"
12771 "Yes");
12772
12773 MockWrite writes[] = {
12774 // First round
12775 kGet,
12776 // Second round
12777 kGetAuth,
12778 // Third round
12779 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3012780 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1012781 kGetAuth,
12782 // Competing request
12783 kGet,
[email protected]c871bce92010-07-15 21:51:1412784 };
12785 MockRead reads[] = {
12786 // First round
12787 kServerChallenge,
12788 // Second round
12789 kServerChallenge,
12790 // Third round
[email protected]eca50e122010-09-11 14:03:3012791 kServerChallenge,
12792 // Fourth round
[email protected]c871bce92010-07-15 21:51:1412793 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1012794 // Competing response
12795 kSuccess,
[email protected]c871bce92010-07-15 21:51:1412796 };
12797 StaticSocketDataProvider data_provider(reads, arraysize(reads),
12798 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0712799 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1412800
thestig9d3bb0c2015-01-24 00:49:5112801 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1012802
12803 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1412804 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2012805 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1412806 if (rv == ERR_IO_PENDING)
12807 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112808 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612809 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212810 ASSERT_TRUE(response);
12811 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812812 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112813 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12814 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412815
[email protected]7ef4cbbb2011-02-06 11:19:1012816 // In between rounds, another request comes in for the same domain.
12817 // It should not be able to grab the TCP socket that trans has already
12818 // claimed.
bnc691fda62016-08-12 00:43:1612819 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112820 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2012821 rv = trans_compete.Start(&request, callback_compete.callback(),
12822 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112823 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1012824 // callback_compete.WaitForResult at this point would stall forever,
12825 // since the HttpNetworkTransaction does not release the request back to
12826 // the pool until after authentication completes.
12827
12828 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1412829 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612830 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412831 if (rv == ERR_IO_PENDING)
12832 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112833 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612834 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212835 ASSERT_TRUE(response);
12836 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812837 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112838 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12839 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1412840
[email protected]7ef4cbbb2011-02-06 11:19:1012841 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1412842 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612843 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1412844 if (rv == ERR_IO_PENDING)
12845 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112846 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612847 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212848 ASSERT_TRUE(response);
12849 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812850 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3112851 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
12852 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3012853
[email protected]7ef4cbbb2011-02-06 11:19:1012854 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3012855 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1612856 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3012857 if (rv == ERR_IO_PENDING)
12858 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0112859 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612860 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212861 ASSERT_TRUE(response);
12862 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2812863 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012864
asanka463ca4262016-11-16 02:34:3112865 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
12866 // auth handler should transition to a DONE state in concert with the remote
12867 // server. But that's not something we can test here with a mock handler.
12868 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
12869 auth_handler->state());
12870
[email protected]7ef4cbbb2011-02-06 11:19:1012871 // Read the body since the fourth round was successful. This will also
12872 // release the socket back to the pool.
12873 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
bnc691fda62016-08-12 00:43:1612874 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012875 if (rv == ERR_IO_PENDING)
12876 rv = callback.WaitForResult();
12877 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612878 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012879 EXPECT_EQ(0, rv);
12880 // There are still 0 idle sockets, since the trans_compete transaction
12881 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2812882 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1012883
12884 // The competing request can now finish. Wait for the headers and then
12885 // read the body.
12886 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0112887 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1612888 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012889 if (rv == ERR_IO_PENDING)
12890 rv = callback.WaitForResult();
12891 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1612892 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1012893 EXPECT_EQ(0, rv);
12894
12895 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2812896 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1412897}
12898
[email protected]65041fa2010-05-21 06:56:5312899// This tests the case that a request is issued via http instead of spdy after
12900// npn is negotiated.
bncd16676a2016-07-20 16:23:0112901TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5312902 HttpRequestInfo request;
12903 request.method = "GET";
bncce36dca22015-04-21 22:11:2312904 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312905
12906 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312907 MockWrite(
12908 "GET / HTTP/1.1\r\n"
12909 "Host: www.example.org\r\n"
12910 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312911 };
12912
12913 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212914 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312915 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212916 MockRead("\r\n"),
12917 MockRead("hello world"),
12918 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312919 };
12920
[email protected]8ddf8322012-02-23 18:08:0612921 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612922 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5312923
[email protected]bb88e1d32013-05-03 23:11:0712924 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312925
12926 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12927 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712928 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312929
[email protected]49639fa2011-12-20 23:22:4112930 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312931
danakj1fd259a02016-04-16 03:17:0912932 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612933 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5312934
tfarina42834112016-09-22 13:38:2012935 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5312936
robpercival214763f2016-07-01 23:27:0112937 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12938 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5312939
bnc691fda62016-08-12 00:43:1612940 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212941 ASSERT_TRUE(response);
12942 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312943 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12944
12945 std::string response_data;
bnc691fda62016-08-12 00:43:1612946 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5312947 EXPECT_EQ("hello world", response_data);
12948
12949 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212950 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312951}
[email protected]26ef6582010-06-24 02:30:4712952
bnc55ff9da2015-08-19 18:42:3512953// Simulate the SSL handshake completing with an NPN negotiation followed by an
12954// immediate server closing of the socket.
12955// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0112956TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4712957 HttpRequestInfo request;
12958 request.method = "GET";
bncce36dca22015-04-21 22:11:2312959 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712960
[email protected]8ddf8322012-02-23 18:08:0612961 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612962 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0712963 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712964
bncdf80d44fd2016-07-15 20:27:4112965 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4912966 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncdf80d44fd2016-07-15 20:27:4112967 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4712968
12969 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612970 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712971 };
12972
rch8e6c6c42015-05-01 14:05:1312973 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12974 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712975 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712976
[email protected]49639fa2011-12-20 23:22:4112977 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712978
danakj1fd259a02016-04-16 03:17:0912979 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612980 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4712981
tfarina42834112016-09-22 13:38:2012982 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112983 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12984 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4712985}
[email protected]65d34382010-07-01 18:12:2612986
[email protected]795cbf82013-07-22 09:37:2712987// A subclass of HttpAuthHandlerMock that records the request URL when
12988// it gets it. This is needed since the auth handler may get destroyed
12989// before we get a chance to query it.
12990class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12991 public:
12992 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12993
dchengb03027d2014-10-21 12:00:2012994 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712995
12996 protected:
dchengb03027d2014-10-21 12:00:2012997 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12998 const HttpRequestInfo* request,
12999 const CompletionCallback& callback,
13000 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713001 *url_ = request->url;
13002 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
13003 credentials, request, callback, auth_token);
13004 }
13005
13006 private:
13007 GURL* url_;
13008};
13009
[email protected]8e6441ca2010-08-19 05:56:3813010// Test that if we cancel the transaction as the connection is completing, that
13011// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113012TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813013 // Setup everything about the connection to complete synchronously, so that
13014 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13015 // for is the callback from the HttpStreamRequest.
13016 // Then cancel the transaction.
13017 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613018 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813019 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613020 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13021 MockRead(SYNCHRONOUS, "hello world"),
13022 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813023 };
13024
[email protected]8e6441ca2010-08-19 05:56:3813025 HttpRequestInfo request;
13026 request.method = "GET";
bncce36dca22015-04-21 22:11:2313027 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3813028
[email protected]bb88e1d32013-05-03 23:11:0713029 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0913030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813031 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913032 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713033
[email protected]8e6441ca2010-08-19 05:56:3813034 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13035 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713036 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813037
[email protected]49639fa2011-12-20 23:22:4113038 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813039
vishal.b62985ca92015-04-17 08:45:5113040 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113041 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113042 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813043 trans.reset(); // Cancel the transaction here.
13044
fdoray92e35a72016-06-10 15:54:5513045 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013046}
13047
[email protected]ecab6e052014-05-16 14:58:1213048// Test that if a transaction is cancelled after receiving the headers, the
13049// stream is drained properly and added back to the socket pool. The main
13050// purpose of this test is to make sure that an HttpStreamParser can be read
13051// from after the HttpNetworkTransaction and the objects it owns have been
13052// deleted.
13053// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113054TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213055 MockRead data_reads[] = {
13056 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13057 MockRead(ASYNC, "Content-Length: 2\r\n"),
13058 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13059 MockRead(ASYNC, "1"),
13060 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13061 // HttpNetworkTransaction has been deleted.
13062 MockRead(ASYNC, "2"),
13063 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13064 };
13065 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
13066 session_deps_.socket_factory->AddSocketDataProvider(&data);
13067
danakj1fd259a02016-04-16 03:17:0913068 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213069
13070 {
13071 HttpRequestInfo request;
13072 request.method = "GET";
bncce36dca22015-04-21 22:11:2313073 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1213074
dcheng48459ac22014-08-26 00:46:4113075 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213076 TestCompletionCallback callback;
13077
tfarina42834112016-09-22 13:38:2013078 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113079 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213080 callback.WaitForResult();
13081
13082 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213083 ASSERT_TRUE(response);
13084 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213085 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13086
13087 // The transaction and HttpRequestInfo are deleted.
13088 }
13089
13090 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513091 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213092
13093 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113094 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213095}
13096
[email protected]76a505b2010-08-25 06:23:0013097// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113098TEST_F(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0313099 session_deps_.proxy_service =
13100 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113101 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713102 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913103 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013104
[email protected]76a505b2010-08-25 06:23:0013105 HttpRequestInfo request;
13106 request.method = "GET";
bncce36dca22015-04-21 22:11:2313107 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013108
13109 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313110 MockWrite(
13111 "GET http://www.example.org/ HTTP/1.1\r\n"
13112 "Host: www.example.org\r\n"
13113 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013114 };
13115
13116 MockRead data_reads1[] = {
13117 MockRead("HTTP/1.1 200 OK\r\n"),
13118 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13119 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613120 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013121 };
13122
13123 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13124 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713125 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013126
[email protected]49639fa2011-12-20 23:22:4113127 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013128
bnc691fda62016-08-12 00:43:1613129 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913130 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613131 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913132 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13133 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013134
bnc691fda62016-08-12 00:43:1613135 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013137
13138 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113139 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013140
bnc691fda62016-08-12 00:43:1613141 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213142 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013143
13144 EXPECT_TRUE(response->headers->IsKeepAlive());
13145 EXPECT_EQ(200, response->headers->response_code());
13146 EXPECT_EQ(100, response->headers->GetContentLength());
13147 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713148 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13149 HostPortPair::FromString("myproxy:70")),
13150 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913151 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13152 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13153 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013154 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013155
13156 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613157 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013158 TestLoadTimingNotReusedWithPac(load_timing_info,
13159 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013160}
13161
13162// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113163TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0313164 session_deps_.proxy_service =
13165 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113166 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713167 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913168 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013169
[email protected]76a505b2010-08-25 06:23:0013170 HttpRequestInfo request;
13171 request.method = "GET";
bncce36dca22015-04-21 22:11:2313172 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013173
13174 // Since we have proxy, should try to establish tunnel.
13175 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713176 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13177 "Host: www.example.org:443\r\n"
13178 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013179
rsleevidb16bb02015-11-12 23:47:1713180 MockWrite("GET / HTTP/1.1\r\n"
13181 "Host: www.example.org\r\n"
13182 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013183 };
13184
13185 MockRead data_reads1[] = {
13186 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13187
13188 MockRead("HTTP/1.1 200 OK\r\n"),
13189 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13190 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613191 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013192 };
13193
13194 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13195 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713196 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613197 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713198 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013199
[email protected]49639fa2011-12-20 23:22:4113200 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013201
bnc691fda62016-08-12 00:43:1613202 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913203 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613204 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913205 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13206 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013207
bnc691fda62016-08-12 00:43:1613208 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113209 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013210
13211 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113212 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613213 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013214 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013215 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013216 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13217 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013218 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013219 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013220 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13221 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013222
bnc691fda62016-08-12 00:43:1613223 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213224 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013225
13226 EXPECT_TRUE(response->headers->IsKeepAlive());
13227 EXPECT_EQ(200, response->headers->response_code());
13228 EXPECT_EQ(100, response->headers->GetContentLength());
13229 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13230 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713231 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13232 HostPortPair::FromString("myproxy:70")),
13233 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913234 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13235 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13236 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013237
13238 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613239 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013240 TestLoadTimingNotReusedWithPac(load_timing_info,
13241 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013242}
13243
rsleevidb16bb02015-11-12 23:47:1713244// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13245// literal host.
bncd16676a2016-07-20 16:23:0113246TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
rsleevidb16bb02015-11-12 23:47:1713247 session_deps_.proxy_service =
13248 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
13249 BoundTestNetLog log;
13250 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913251 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713252
13253 HttpRequestInfo request;
13254 request.method = "GET";
13255 request.url = GURL("https://[::1]:443/");
13256
13257 // Since we have proxy, should try to establish tunnel.
13258 MockWrite data_writes1[] = {
13259 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
13260 "Host: [::1]:443\r\n"
13261 "Proxy-Connection: keep-alive\r\n\r\n"),
13262
13263 MockWrite("GET / HTTP/1.1\r\n"
13264 "Host: [::1]\r\n"
13265 "Connection: keep-alive\r\n\r\n"),
13266 };
13267
13268 MockRead data_reads1[] = {
13269 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13270
13271 MockRead("HTTP/1.1 200 OK\r\n"),
13272 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13273 MockRead("Content-Length: 100\r\n\r\n"),
13274 MockRead(SYNCHRONOUS, OK),
13275 };
13276
13277 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13278 data_writes1, arraysize(data_writes1));
13279 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13280 SSLSocketDataProvider ssl(ASYNC, OK);
13281 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13282
13283 TestCompletionCallback callback1;
13284
bnc691fda62016-08-12 00:43:1613285 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1713286
bnc691fda62016-08-12 00:43:1613287 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113288 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1713289
13290 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113291 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1713292 TestNetLogEntry::List entries;
13293 log.GetEntries(&entries);
13294 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013295 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13296 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713297 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013298 entries, pos,
13299 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13300 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1713301
bnc691fda62016-08-12 00:43:1613302 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213303 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1713304
13305 EXPECT_TRUE(response->headers->IsKeepAlive());
13306 EXPECT_EQ(200, response->headers->response_code());
13307 EXPECT_EQ(100, response->headers->GetContentLength());
13308 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13309 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713310 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13311 HostPortPair::FromString("myproxy:70")),
13312 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1713313
13314 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613315 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1713316 TestLoadTimingNotReusedWithPac(load_timing_info,
13317 CONNECT_TIMING_HAS_SSL_TIMES);
13318}
13319
[email protected]76a505b2010-08-25 06:23:0013320// Test a basic HTTPS GET request through a proxy, but the server hangs up
13321// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0113322TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0313323 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5113324 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713325 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913326 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013327
[email protected]76a505b2010-08-25 06:23:0013328 HttpRequestInfo request;
13329 request.method = "GET";
bncce36dca22015-04-21 22:11:2313330 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0013331
13332 // Since we have proxy, should try to establish tunnel.
13333 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713334 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13335 "Host: www.example.org:443\r\n"
13336 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013337
rsleevidb16bb02015-11-12 23:47:1713338 MockWrite("GET / HTTP/1.1\r\n"
13339 "Host: www.example.org\r\n"
13340 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013341 };
13342
13343 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0613344 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0013345 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613346 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0013347 };
13348
13349 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
13350 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0713351 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613352 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713353 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013354
[email protected]49639fa2011-12-20 23:22:4113355 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013356
bnc691fda62016-08-12 00:43:1613357 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5013358
bnc691fda62016-08-12 00:43:1613359 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113360 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013361
13362 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113363 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4613364 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013365 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013366 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013367 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13368 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013369 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013370 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013371 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13372 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013373}
13374
[email protected]749eefa82010-09-13 22:14:0313375// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0113376TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncdf80d44fd2016-07-15 20:27:4113377 SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4913378 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113379 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0313380
bnc42331402016-07-25 13:36:1513381 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113382 SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0313383 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113384 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0313385 };
13386
rch8e6c6c42015-05-01 14:05:1313387 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
13388 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713389 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0313390
[email protected]8ddf8322012-02-23 18:08:0613391 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613392 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713393 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0313394
danakj1fd259a02016-04-16 03:17:0913395 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0313396
13397 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2313398 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013399 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5313400 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2713401 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213402 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0313403
13404 HttpRequestInfo request;
13405 request.method = "GET";
bncce36dca22015-04-21 22:11:2313406 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0313407
13408 // This is the important line that marks this as a preconnect.
13409 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
13410
bnc691fda62016-08-12 00:43:1613411 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0313412
[email protected]41d64e82013-07-03 22:44:2613413 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013414 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113415 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13416 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0313417}
13418
[email protected]73b8dd222010-11-11 19:55:2413419// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1613420// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0213421void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0713422 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2913423 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713424 request_info.url = GURL("https://www.example.com/");
13425 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913426 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713427
[email protected]8ddf8322012-02-23 18:08:0613428 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2913429 MockWrite data_writes[] = {
13430 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2413431 };
ttuttle859dc7a2015-04-23 19:42:2913432 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0713433 session_deps_.socket_factory->AddSocketDataProvider(&data);
13434 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2413435
danakj1fd259a02016-04-16 03:17:0913436 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613437 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2413438
[email protected]49639fa2011-12-20 23:22:4113439 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013440 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2913441 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2413442 rv = callback.WaitForResult();
13443 ASSERT_EQ(error, rv);
13444}
13445
bncd16676a2016-07-20 16:23:0113446TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2413447 // Just check a grab bag of cert errors.
13448 static const int kErrors[] = {
13449 ERR_CERT_COMMON_NAME_INVALID,
13450 ERR_CERT_AUTHORITY_INVALID,
13451 ERR_CERT_DATE_INVALID,
13452 };
13453 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0613454 CheckErrorIsPassedBack(kErrors[i], ASYNC);
13455 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2413456 }
13457}
13458
[email protected]bd0b6772011-01-11 19:59:3013459// Ensure that a client certificate is removed from the SSL client auth
13460// cache when:
13461// 1) No proxy is involved.
13462// 2) TLS False Start is disabled.
13463// 3) The initial TLS handshake requests a client certificate.
13464// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113465TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913466 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713467 request_info.url = GURL("https://www.example.com/");
13468 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913469 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713470
[email protected]bd0b6772011-01-11 19:59:3013471 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113472 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013473
13474 // [ssl_]data1 contains the data for the first SSL handshake. When a
13475 // CertificateRequest is received for the first time, the handshake will
13476 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2913477 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013478 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713479 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913480 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713481 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013482
13483 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
13484 // False Start is not being used, the result of the SSL handshake will be
13485 // returned as part of the SSLClientSocket::Connect() call. This test
13486 // matches the result of a server sending a handshake_failure alert,
13487 // rather than a Finished message, because it requires a client
13488 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2913489 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013490 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713491 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913492 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713493 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013494
13495 // [ssl_]data3 contains the data for the third SSL handshake. When a
13496 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213497 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
13498 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3013499 // of the HttpNetworkTransaction. Because this test failure is due to
13500 // requiring a client certificate, this fallback handshake should also
13501 // fail.
ttuttle859dc7a2015-04-23 19:42:2913502 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3013503 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713504 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913505 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713506 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013507
[email protected]80c75f682012-05-26 16:22:1713508 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
13509 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4213510 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
13511 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1713512 // of the HttpNetworkTransaction. Because this test failure is due to
13513 // requiring a client certificate, this fallback handshake should also
13514 // fail.
ttuttle859dc7a2015-04-23 19:42:2913515 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1713516 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713517 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913518 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713519 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713520
danakj1fd259a02016-04-16 03:17:0913521 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613522 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013523
[email protected]bd0b6772011-01-11 19:59:3013524 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4113525 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013526 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113527 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013528
13529 // Complete the SSL handshake, which should abort due to requiring a
13530 // client certificate.
13531 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113532 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013533
13534 // Indicate that no certificate should be supplied. From the perspective
13535 // of SSLClientCertCache, NULL is just as meaningful as a real
13536 // certificate, so this is the same as supply a
13537 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613538 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113539 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013540
13541 // Ensure the certificate was added to the client auth cache before
13542 // allowing the connection to continue restarting.
13543 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413544 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113545 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413546 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213547 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013548
13549 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713550 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13551 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013552 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113553 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013554
13555 // Ensure that the client certificate is removed from the cache on a
13556 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113557 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413558 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013559}
13560
13561// Ensure that a client certificate is removed from the SSL client auth
13562// cache when:
13563// 1) No proxy is involved.
13564// 2) TLS False Start is enabled.
13565// 3) The initial TLS handshake requests a client certificate.
13566// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0113567TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2913568 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2713569 request_info.url = GURL("https://www.example.com/");
13570 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913571 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2713572
[email protected]bd0b6772011-01-11 19:59:3013573 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113574 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3013575
13576 // When TLS False Start is used, SSLClientSocket::Connect() calls will
13577 // return successfully after reading up to the peer's Certificate message.
13578 // This is to allow the caller to call SSLClientSocket::Write(), which can
13579 // enqueue application data to be sent in the same packet as the
13580 // ChangeCipherSpec and Finished messages.
13581 // The actual handshake will be finished when SSLClientSocket::Read() is
13582 // called, which expects to process the peer's ChangeCipherSpec and
13583 // Finished messages. If there was an error negotiating with the peer,
13584 // such as due to the peer requiring a client certificate when none was
13585 // supplied, the alert sent by the peer won't be processed until Read() is
13586 // called.
13587
13588 // Like the non-False Start case, when a client certificate is requested by
13589 // the peer, the handshake is aborted during the Connect() call.
13590 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2913591 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3013592 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713593 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913594 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713595 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3013596
13597 // When a client certificate is supplied, Connect() will not be aborted
13598 // when the peer requests the certificate. Instead, the handshake will
13599 // artificially succeed, allowing the caller to write the HTTP request to
13600 // the socket. The handshake messages are not processed until Read() is
13601 // called, which then detects that the handshake was aborted, due to the
13602 // peer sending a handshake_failure because it requires a client
13603 // certificate.
ttuttle859dc7a2015-04-23 19:42:2913604 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013605 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913607 MockRead data2_reads[] = {
13608 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3013609 };
ttuttle859dc7a2015-04-23 19:42:2913610 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713611 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3013612
13613 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1713614 // the data for the SSL handshake once the TLSv1.1 connection falls back to
13615 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913616 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3013617 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713618 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913619 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713620 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3013621
[email protected]80c75f682012-05-26 16:22:1713622 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
13623 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2913624 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1713625 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2913627 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713628 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1713629
[email protected]7799de12013-05-30 05:52:5113630 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2913631 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5113632 ssl_data5.cert_request_info = cert_request.get();
13633 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2913634 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5113635 session_deps_.socket_factory->AddSocketDataProvider(&data5);
13636
danakj1fd259a02016-04-16 03:17:0913637 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613638 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3013639
[email protected]bd0b6772011-01-11 19:59:3013640 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4113641 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013642 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113643 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013644
13645 // Complete the SSL handshake, which should abort due to requiring a
13646 // client certificate.
13647 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113648 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3013649
13650 // Indicate that no certificate should be supplied. From the perspective
13651 // of SSLClientCertCache, NULL is just as meaningful as a real
13652 // certificate, so this is the same as supply a
13653 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613654 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113655 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3013656
13657 // Ensure the certificate was added to the client auth cache before
13658 // allowing the connection to continue restarting.
13659 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413660 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113661 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413662 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213663 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3013664
[email protected]bd0b6772011-01-11 19:59:3013665 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1713666 // then consume ssl_data3 and ssl_data4, both of which should also fail.
13667 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3013668 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113669 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3013670
13671 // Ensure that the client certificate is removed from the cache on a
13672 // handshake failure.
[email protected]791879c2013-12-17 07:22:4113673 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413674 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3013675}
13676
[email protected]8c405132011-01-11 22:03:1813677// Ensure that a client certificate is removed from the SSL client auth
13678// cache when:
13679// 1) An HTTPS proxy is involved.
13680// 3) The HTTPS proxy requests a client certificate.
13681// 4) The client supplies an invalid/unacceptable certificate for the
13682// proxy.
13683// The test is repeated twice, first for connecting to an HTTPS endpoint,
13684// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0113685TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0313686 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5113687 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713688 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1813689
13690 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4113691 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1813692
13693 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
13694 // [ssl_]data[1-3]. Rather than represending the endpoint
13695 // (www.example.com:443), they represent failures with the HTTPS proxy
13696 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2913697 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1813698 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713699 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2913700 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713701 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1813702
ttuttle859dc7a2015-04-23 19:42:2913703 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813704 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713705 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2913706 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713707 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1813708
[email protected]80c75f682012-05-26 16:22:1713709 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
13710#if 0
ttuttle859dc7a2015-04-23 19:42:2913711 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1813712 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0713713 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2913714 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0713715 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1713716#endif
[email protected]8c405132011-01-11 22:03:1813717
ttuttle859dc7a2015-04-23 19:42:2913718 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813719 requests[0].url = GURL("https://www.example.com/");
13720 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913721 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813722
13723 requests[1].url = GURL("http://www.example.com/");
13724 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913725 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813726
13727 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713728 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1813731
13732 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113733 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2013734 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113735 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813736
13737 // Complete the SSL handshake, which should abort due to requiring a
13738 // client certificate.
13739 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113740 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1813741
13742 // Indicate that no certificate should be supplied. From the perspective
13743 // of SSLClientCertCache, NULL is just as meaningful as a real
13744 // certificate, so this is the same as supply a
13745 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1613746 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0113747 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1813748
13749 // Ensure the certificate was added to the client auth cache before
13750 // allowing the connection to continue restarting.
13751 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413752 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113753 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413754 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213755 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813756 // Ensure the certificate was NOT cached for the endpoint. This only
13757 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113758 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413759 HostPortPair("www.example.com", 443), &client_cert,
13760 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813761
13762 // Restart the handshake. This will consume ssl_data2, which fails, and
13763 // then consume ssl_data3, which should also fail. The result code is
13764 // checked against what ssl_data3 should return.
13765 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113766 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1813767
13768 // Now that the new handshake has failed, ensure that the client
13769 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113770 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413771 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113772 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413773 HostPortPair("www.example.com", 443), &client_cert,
13774 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813775 }
13776}
13777
bncd16676a2016-07-20 16:23:0113778TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4613779 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1913780 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913781 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4613782
bnc032658ba2016-09-26 18:17:1513783 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4613784
bncdf80d44fd2016-07-15 20:27:4113785 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913786 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813787 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113788 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713789 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613790 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113791 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613792 };
bnc42331402016-07-25 13:36:1513793 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113794 SpdySerializedFrame host1_resp_body(
13795 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513796 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113797 SpdySerializedFrame host2_resp_body(
13798 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613799 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113800 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13801 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313802 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613803 };
13804
eroman36d84e54432016-03-17 03:23:0213805 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213806 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313807 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13808 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713809 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613810
[email protected]aa22b242011-11-16 18:58:2913811 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613812 HttpRequestInfo request1;
13813 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313814 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613815 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013816 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613817
tfarina42834112016-09-22 13:38:2013818 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113819 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13820 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613821
13822 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213823 ASSERT_TRUE(response);
13824 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213825 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613826
13827 std::string response_data;
robpercival214763f2016-07-01 23:27:0113828 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613829 EXPECT_EQ("hello!", response_data);
13830
bnca4d611d2016-09-22 19:55:3713831 // Preload mail.example.com into HostCache.
13832 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1013833 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613834 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1013835 std::unique_ptr<HostResolver::Request> request;
13836 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13837 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2013838 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113839 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4713840 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113841 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4613842
13843 HttpRequestInfo request2;
13844 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713845 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4613846 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013847 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613848
tfarina42834112016-09-22 13:38:2013849 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113850 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13851 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613852
13853 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213854 ASSERT_TRUE(response);
13855 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213856 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613857 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213858 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113859 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4613860 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613861}
13862
bncd16676a2016-07-20 16:23:0113863TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0213864 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1913865 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0913866 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213867
bnc032658ba2016-09-26 18:17:1513868 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0213869
bncdf80d44fd2016-07-15 20:27:4113870 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4913871 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813872 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4113873 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3713874 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213875 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4113876 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213877 };
bnc42331402016-07-25 13:36:1513878 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4113879 SpdySerializedFrame host1_resp_body(
13880 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1513881 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4113882 SpdySerializedFrame host2_resp_body(
13883 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213884 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113885 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
13886 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1313887 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213888 };
13889
eroman36d84e54432016-03-17 03:23:0213890 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213891 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313892 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13893 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713894 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213895
13896 TestCompletionCallback callback;
13897 HttpRequestInfo request1;
13898 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313899 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213900 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013901 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213902
tfarina42834112016-09-22 13:38:2013903 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113904 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13905 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213906
13907 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213908 ASSERT_TRUE(response);
13909 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213910 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213911
13912 std::string response_data;
robpercival214763f2016-07-01 23:27:0113913 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213914 EXPECT_EQ("hello!", response_data);
13915
13916 HttpRequestInfo request2;
13917 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3713918 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0213919 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013920 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213921
tfarina42834112016-09-22 13:38:2013922 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113923 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13924 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213925
13926 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213927 ASSERT_TRUE(response);
13928 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213929 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213930 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213931 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0113932 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0213933 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213934}
13935
bnc8016c1f2017-03-31 02:11:2913936// Regression test for https://crbug.com/546991.
13937// The server might not be able to serve an IP pooled request, and might send a
13938// 421 Misdirected Request response status to indicate this.
13939// HttpNetworkTransaction should reset the request and retry without IP pooling.
13940TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
13941 // Two hosts resolve to the same IP address.
13942 const std::string ip_addr = "1.2.3.4";
13943 IPAddress ip;
13944 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
13945 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13946
Jeremy Roman0579ed62017-08-29 15:56:1913947 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2913948 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
13949 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
13950
13951 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13952
13953 // Two requests on the first connection.
13954 SpdySerializedFrame req1(
13955 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
13956 spdy_util_.UpdateWithStreamDestruction(1);
13957 SpdySerializedFrame req2(
13958 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
13959 SpdySerializedFrame rst(
13960 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
13961 MockWrite writes1[] = {
13962 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
13963 CreateMockWrite(rst, 6),
13964 };
13965
13966 // The first one succeeds, the second gets error 421 Misdirected Request.
13967 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13968 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
13969 SpdyHeaderBlock response_headers;
13970 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
13971 SpdySerializedFrame resp2(
13972 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
13973 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
13974 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
13975
13976 MockConnect connect1(ASYNC, OK, peer_addr);
13977 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
13978 arraysize(writes1));
13979 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13980
13981 AddSSLSocketData();
13982
13983 // Retry the second request on a second connection.
13984 SpdyTestUtil spdy_util2;
13985 SpdySerializedFrame req3(
13986 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
13987 MockWrite writes2[] = {
13988 CreateMockWrite(req3, 0),
13989 };
13990
13991 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
13992 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
13993 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
13994 MockRead(ASYNC, 0, 3)};
13995
13996 MockConnect connect2(ASYNC, OK, peer_addr);
13997 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
13998 arraysize(writes2));
13999 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14000
14001 AddSSLSocketData();
14002
14003 // Preload mail.example.org into HostCache.
14004 HostPortPair host_port("mail.example.org", 443);
14005 HostResolver::RequestInfo resolve_info(host_port);
14006 AddressList ignored;
14007 std::unique_ptr<HostResolver::Request> request;
14008 TestCompletionCallback callback;
14009 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14010 &ignored, callback.callback(),
14011 &request, NetLogWithSource());
14012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14013 rv = callback.WaitForResult();
14014 EXPECT_THAT(rv, IsOk());
14015
14016 HttpRequestInfo request1;
14017 request1.method = "GET";
14018 request1.url = GURL("https://www.example.org/");
14019 request1.load_flags = 0;
14020 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14021
14022 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14023 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14024 rv = callback.WaitForResult();
14025 EXPECT_THAT(rv, IsOk());
14026
14027 const HttpResponseInfo* response = trans1.GetResponseInfo();
14028 ASSERT_TRUE(response);
14029 ASSERT_TRUE(response->headers);
14030 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14031 EXPECT_TRUE(response->was_fetched_via_spdy);
14032 EXPECT_TRUE(response->was_alpn_negotiated);
14033 std::string response_data;
14034 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14035 EXPECT_EQ("hello!", response_data);
14036
14037 HttpRequestInfo request2;
14038 request2.method = "GET";
14039 request2.url = GURL("https://mail.example.org/");
14040 request2.load_flags = 0;
14041 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14042
14043 BoundTestNetLog log;
14044 rv = trans2.Start(&request2, callback.callback(), log.bound());
14045 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14046 rv = callback.WaitForResult();
14047 EXPECT_THAT(rv, IsOk());
14048
14049 response = trans2.GetResponseInfo();
14050 ASSERT_TRUE(response);
14051 ASSERT_TRUE(response->headers);
14052 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14053 EXPECT_TRUE(response->was_fetched_via_spdy);
14054 EXPECT_TRUE(response->was_alpn_negotiated);
14055 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14056 EXPECT_EQ("hello!", response_data);
14057
14058 TestNetLogEntry::List entries;
14059 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914060 ExpectLogContainsSomewhere(
14061 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914062 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914063}
14064
14065// Test that HTTP 421 responses are properly returned to the caller if received
14066// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14067// portions of the response.
14068TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14069 // Two hosts resolve to the same IP address.
14070 const std::string ip_addr = "1.2.3.4";
14071 IPAddress ip;
14072 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14073 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14074
Jeremy Roman0579ed62017-08-29 15:56:1914075 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914076 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14077 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14078
14079 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14080
14081 // Two requests on the first connection.
14082 SpdySerializedFrame req1(
14083 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14084 spdy_util_.UpdateWithStreamDestruction(1);
14085 SpdySerializedFrame req2(
14086 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
14087 SpdySerializedFrame rst(
14088 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL));
14089 MockWrite writes1[] = {
14090 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14091 CreateMockWrite(rst, 6),
14092 };
14093
14094 // The first one succeeds, the second gets error 421 Misdirected Request.
14095 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14096 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14097 SpdyHeaderBlock response_headers;
14098 response_headers[SpdyTestUtil::GetStatusKey()] = "421";
14099 SpdySerializedFrame resp2(
14100 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14101 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14102 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14103
14104 MockConnect connect1(ASYNC, OK, peer_addr);
14105 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1,
14106 arraysize(writes1));
14107 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14108
14109 AddSSLSocketData();
14110
14111 // Retry the second request on a second connection. It returns 421 Misdirected
14112 // Retry again.
14113 SpdyTestUtil spdy_util2;
14114 SpdySerializedFrame req3(
14115 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14116 MockWrite writes2[] = {
14117 CreateMockWrite(req3, 0),
14118 };
14119
14120 SpdySerializedFrame resp3(
14121 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
14122 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
14123 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14124 MockRead(ASYNC, 0, 3)};
14125
14126 MockConnect connect2(ASYNC, OK, peer_addr);
14127 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2,
14128 arraysize(writes2));
14129 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14130
14131 AddSSLSocketData();
14132
14133 // Preload mail.example.org into HostCache.
14134 HostPortPair host_port("mail.example.org", 443);
14135 HostResolver::RequestInfo resolve_info(host_port);
14136 AddressList ignored;
14137 std::unique_ptr<HostResolver::Request> request;
14138 TestCompletionCallback callback;
14139 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14140 &ignored, callback.callback(),
14141 &request, NetLogWithSource());
14142 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14143 rv = callback.WaitForResult();
14144 EXPECT_THAT(rv, IsOk());
14145
14146 HttpRequestInfo request1;
14147 request1.method = "GET";
14148 request1.url = GURL("https://www.example.org/");
14149 request1.load_flags = 0;
14150 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14151
14152 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14153 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14154 rv = callback.WaitForResult();
14155 EXPECT_THAT(rv, IsOk());
14156
14157 const HttpResponseInfo* response = trans1.GetResponseInfo();
14158 ASSERT_TRUE(response);
14159 ASSERT_TRUE(response->headers);
14160 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14161 EXPECT_TRUE(response->was_fetched_via_spdy);
14162 EXPECT_TRUE(response->was_alpn_negotiated);
14163 std::string response_data;
14164 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14165 EXPECT_EQ("hello!", response_data);
14166
14167 HttpRequestInfo request2;
14168 request2.method = "GET";
14169 request2.url = GURL("https://mail.example.org/");
14170 request2.load_flags = 0;
14171 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14172
14173 BoundTestNetLog log;
14174 rv = trans2.Start(&request2, callback.callback(), log.bound());
14175 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14176 rv = callback.WaitForResult();
14177 EXPECT_THAT(rv, IsOk());
14178
14179 // After a retry, the 421 Misdirected Request is reported back up to the
14180 // caller.
14181 response = trans2.GetResponseInfo();
14182 ASSERT_TRUE(response);
14183 ASSERT_TRUE(response->headers);
14184 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14185 EXPECT_TRUE(response->was_fetched_via_spdy);
14186 EXPECT_TRUE(response->was_alpn_negotiated);
14187 EXPECT_TRUE(response->ssl_info.cert);
14188 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14189 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914190}
14191
bnc6dcd8192017-05-25 20:11:5014192class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614193 public:
14194 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014195 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2014196 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4614197
dchengb03027d2014-10-21 12:00:2014198 int ResolveFromCache(const RequestInfo& info,
14199 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014200 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014201 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014202 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014203 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614204 return rv;
14205 }
14206
[email protected]e3ceb682011-06-28 23:55:4614207 private:
[email protected]e3ceb682011-06-28 23:55:4614208 const HostPortPair host_port_;
14209};
14210
bncd16676a2016-07-20 16:23:0114211TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314212 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614213 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914214 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714215 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914216 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614217
bnc032658ba2016-09-26 18:17:1514218 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614219
bncdf80d44fd2016-07-15 20:27:4114220 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914221 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814222 spdy_util_.UpdateWithStreamDestruction(1);
bncdf80d44fd2016-07-15 20:27:4114223 SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714224 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614225 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114226 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614227 };
bnc42331402016-07-25 13:36:1514228 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114229 SpdySerializedFrame host1_resp_body(
14230 spdy_util_.ConstructSpdyDataFrame(1, true));
bnc42331402016-07-25 13:36:1514231 SpdySerializedFrame host2_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114232 SpdySerializedFrame host2_resp_body(
14233 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614234 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114235 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14236 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314237 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614238 };
14239
eroman36d84e54432016-03-17 03:23:0214240 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214241 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1314242 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
14243 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0714244 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614245
[email protected]aa22b242011-11-16 18:58:2914246 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614247 HttpRequestInfo request1;
14248 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314249 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614250 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014251 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614252
tfarina42834112016-09-22 13:38:2014253 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114254 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14255 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614256
14257 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214258 ASSERT_TRUE(response);
14259 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214260 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614261
14262 std::string response_data;
robpercival214763f2016-07-01 23:27:0114263 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614264 EXPECT_EQ("hello!", response_data);
14265
14266 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3714267 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4614268 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014269 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5014270 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14271 &ignored, callback.callback(),
14272 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114273 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714274 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114275 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614276
14277 HttpRequestInfo request2;
14278 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714279 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614280 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014281 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614282
tfarina42834112016-09-22 13:38:2014283 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114284 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14285 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614286
14287 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214288 ASSERT_TRUE(response);
14289 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214290 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614291 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214292 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114293 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614294 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614295}
14296
bncd16676a2016-07-20 16:23:0114297TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2314298 const std::string https_url = "https://www.example.org:8080/";
14299 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414300
14301 // SPDY GET for HTTPS URL
bncdf80d44fd2016-07-15 20:27:4114302 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914303 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0414304
14305 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114306 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0414307 };
14308
bnc42331402016-07-25 13:36:1514309 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114310 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14311 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5914312 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0414313
rch8e6c6c42015-05-01 14:05:1314314 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14315 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414316 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714317 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414318
14319 // HTTP GET for the HTTP URL
14320 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1314321 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3414322 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314323 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3414324 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0414325 };
14326
14327 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1314328 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
14329 MockRead(ASYNC, 2, "hello"),
14330 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0414331 };
14332
rch8e6c6c42015-05-01 14:05:1314333 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14334 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0414335
[email protected]8450d722012-07-02 19:14:0414336 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614337 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714338 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14339 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14340 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0414341
danakj1fd259a02016-04-16 03:17:0914342 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0414343
14344 // Start the first transaction to set up the SpdySession
14345 HttpRequestInfo request1;
14346 request1.method = "GET";
14347 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414348 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014349 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414350 TestCompletionCallback callback1;
14351 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014352 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514353 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414354
robpercival214763f2016-07-01 23:27:0114355 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414356 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14357
14358 // Now, start the HTTP request
14359 HttpRequestInfo request2;
14360 request2.method = "GET";
14361 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414362 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014363 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414364 TestCompletionCallback callback2;
14365 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014366 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514367 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0414368
robpercival214763f2016-07-01 23:27:0114369 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0414370 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14371}
14372
bnc5452e2a2015-05-08 16:27:4214373// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
14374// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0114375TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2514376 url::SchemeHostPort server("https", "www.example.org", 443);
14377 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4214378
bnc8bef8da22016-05-30 01:28:2514379 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4214380 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614381 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14383
14384 // No data should be read from the alternative, because HTTP/1.1 is
14385 // negotiated.
14386 StaticSocketDataProvider data;
14387 session_deps_.socket_factory->AddSocketDataProvider(&data);
14388
14389 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4614390 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4214391 // mocked. This way the request relies on the alternate Job.
14392 StaticSocketDataProvider data_refused;
14393 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14394 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14395
zhongyi3d4a55e72016-04-22 20:36:4614396 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914397 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014398 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214399 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114400 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214401 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114402 http_server_properties->SetHttp2AlternativeService(
14403 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214404
bnc5452e2a2015-05-08 16:27:4214405 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4614406 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214407 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2514408 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4214409 TestCompletionCallback callback;
14410
14411 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5214412 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2014413 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5214414 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4214415}
14416
bnc40448a532015-05-11 19:13:1414417// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4614418// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1414419// succeeds, the request should succeed, even if the latter fails because
14420// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0114421TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2514422 url::SchemeHostPort server("https", "www.example.org", 443);
14423 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1414424
14425 // Negotiate HTTP/1.1 with alternative.
14426 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614427 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414428 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
14429
14430 // No data should be read from the alternative, because HTTP/1.1 is
14431 // negotiated.
14432 StaticSocketDataProvider data;
14433 session_deps_.socket_factory->AddSocketDataProvider(&data);
14434
zhongyi3d4a55e72016-04-22 20:36:4614435 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1414436 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614437 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1414438 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
14439
14440 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2514441 MockWrite("GET / HTTP/1.1\r\n"
14442 "Host: www.example.org\r\n"
14443 "Connection: keep-alive\r\n\r\n"),
14444 MockWrite("GET /second HTTP/1.1\r\n"
14445 "Host: www.example.org\r\n"
14446 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1414447 };
14448
14449 MockRead http_reads[] = {
14450 MockRead("HTTP/1.1 200 OK\r\n"),
14451 MockRead("Content-Type: text/html\r\n"),
14452 MockRead("Content-Length: 6\r\n\r\n"),
14453 MockRead("foobar"),
14454 MockRead("HTTP/1.1 200 OK\r\n"),
14455 MockRead("Content-Type: text/html\r\n"),
14456 MockRead("Content-Length: 7\r\n\r\n"),
14457 MockRead("another"),
14458 };
14459 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14460 http_writes, arraysize(http_writes));
14461 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14462
zhongyi3d4a55e72016-04-22 20:36:4614463 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914464 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014465 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1414466 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114467 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214468 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114469 http_server_properties->SetHttp2AlternativeService(
14470 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1414471
14472 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14473 HttpRequestInfo request1;
14474 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2514475 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1414476 request1.load_flags = 0;
14477 TestCompletionCallback callback1;
14478
tfarina42834112016-09-22 13:38:2014479 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414480 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114481 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414482
14483 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214484 ASSERT_TRUE(response1);
14485 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1414486 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
14487
14488 std::string response_data1;
robpercival214763f2016-07-01 23:27:0114489 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1414490 EXPECT_EQ("foobar", response_data1);
14491
14492 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
14493 // for alternative service.
14494 EXPECT_TRUE(
14495 http_server_properties->IsAlternativeServiceBroken(alternative_service));
14496
zhongyi3d4a55e72016-04-22 20:36:4614497 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1414498 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4614499 // to server.
bnc40448a532015-05-11 19:13:1414500 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14501 HttpRequestInfo request2;
14502 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2514503 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1414504 request2.load_flags = 0;
14505 TestCompletionCallback callback2;
14506
tfarina42834112016-09-22 13:38:2014507 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1414508 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0114509 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1414510
14511 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214512 ASSERT_TRUE(response2);
14513 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1414514 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
14515
14516 std::string response_data2;
robpercival214763f2016-07-01 23:27:0114517 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1414518 EXPECT_EQ("another", response_data2);
14519}
14520
bnc5452e2a2015-05-08 16:27:4214521// Alternative service requires HTTP/2 (or SPDY), but there is already a
14522// HTTP/1.1 socket open to the alternative server. That socket should not be
14523// used.
bncd16676a2016-07-20 16:23:0114524TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4614525 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4214526 HostPortPair alternative("alternative.example.org", 443);
14527 std::string origin_url = "https://origin.example.org:443";
14528 std::string alternative_url = "https://alternative.example.org:443";
14529
14530 // Negotiate HTTP/1.1 with alternative.example.org.
14531 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614532 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4214533 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14534
14535 // HTTP/1.1 data for |request1| and |request2|.
14536 MockWrite http_writes[] = {
14537 MockWrite(
14538 "GET / HTTP/1.1\r\n"
14539 "Host: alternative.example.org\r\n"
14540 "Connection: keep-alive\r\n\r\n"),
14541 MockWrite(
14542 "GET / HTTP/1.1\r\n"
14543 "Host: alternative.example.org\r\n"
14544 "Connection: keep-alive\r\n\r\n"),
14545 };
14546
14547 MockRead http_reads[] = {
14548 MockRead(
14549 "HTTP/1.1 200 OK\r\n"
14550 "Content-Type: text/html; charset=iso-8859-1\r\n"
14551 "Content-Length: 40\r\n\r\n"
14552 "first HTTP/1.1 response from alternative"),
14553 MockRead(
14554 "HTTP/1.1 200 OK\r\n"
14555 "Content-Type: text/html; charset=iso-8859-1\r\n"
14556 "Content-Length: 41\r\n\r\n"
14557 "second HTTP/1.1 response from alternative"),
14558 };
14559 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14560 http_writes, arraysize(http_writes));
14561 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14562
14563 // This test documents that an alternate Job should not pool to an already
14564 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4614565 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4214566 StaticSocketDataProvider data_refused;
14567 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
14568 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
14569
zhongyi3d4a55e72016-04-22 20:36:4614570 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0914571 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4014572 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4214573 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2114574 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1214575 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2114576 http_server_properties->SetHttp2AlternativeService(
14577 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4214578
14579 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4214580 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4614581 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214582 request1.method = "GET";
14583 request1.url = GURL(alternative_url);
14584 request1.load_flags = 0;
14585 TestCompletionCallback callback1;
14586
tfarina42834112016-09-22 13:38:2014587 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114588 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614589 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214590 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5214591 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4214592 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214593 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214594 EXPECT_FALSE(response1->was_fetched_via_spdy);
14595 std::string response_data1;
bnc691fda62016-08-12 00:43:1614596 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4214597 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
14598
14599 // Request for origin.example.org, which has an alternative service. This
14600 // will start two Jobs: the alternative looks for connections to pool to,
14601 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4614602 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4214603 // this request fails.
bnc5452e2a2015-05-08 16:27:4214604 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4614605 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214606 request2.method = "GET";
14607 request2.url = GURL(origin_url);
14608 request2.load_flags = 0;
14609 TestCompletionCallback callback2;
14610
tfarina42834112016-09-22 13:38:2014611 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114612 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4214613
14614 // Another transaction to alternative. This is to test that the HTTP/1.1
14615 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4214616 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4614617 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4214618 request3.method = "GET";
14619 request3.url = GURL(alternative_url);
14620 request3.load_flags = 0;
14621 TestCompletionCallback callback3;
14622
tfarina42834112016-09-22 13:38:2014623 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114624 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1614625 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4214626 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5214627 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4214628 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5214629 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4214630 EXPECT_FALSE(response3->was_fetched_via_spdy);
14631 std::string response_data3;
bnc691fda62016-08-12 00:43:1614632 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4214633 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
14634}
14635
bncd16676a2016-07-20 16:23:0114636TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2314637 const std::string https_url = "https://www.example.org:8080/";
14638 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0414639
rdsmithebb50aa2015-11-12 03:44:3814640 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0114641 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3814642
[email protected]8450d722012-07-02 19:14:0414643 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2314644 const HostPortPair host_port_pair("www.example.org", 8080);
bncdf80d44fd2016-07-15 20:27:4114645 SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3414646 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncdf80d44fd2016-07-15 20:27:4114647 SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4914648 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114649 SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0214650 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3914651
14652 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2914653 SpdyHeaderBlock req2_block;
14654 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2314655 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2914656 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4914657 req2_block[spdy_util_.GetPathKey()] = "/";
bncdf80d44fd2016-07-15 20:27:4114658 SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1514659 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0414660
14661 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114662 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
14663 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0414664 };
14665
bncdf80d44fd2016-07-15 20:27:4114666 SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1514667 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114668 SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1514669 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114670 SpdySerializedFrame body1(spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
14671 SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3814672 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncdf80d44fd2016-07-15 20:27:4114673 SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3814674 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bnc42331402016-07-25 13:36:1514675 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
bncdf80d44fd2016-07-15 20:27:4114676 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3314677 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114678 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3314679 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4114680 CreateMockRead(wrapped_resp1, 4),
14681 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3314682 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4114683 CreateMockRead(resp2, 8),
14684 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3314685 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
14686 };
[email protected]8450d722012-07-02 19:14:0414687
mmenke666a6fea2015-12-19 04:16:3314688 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14689 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0414690 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5714691 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0414692
rdsmith82957ad2015-09-16 19:42:0314693 session_deps_.proxy_service =
14694 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5114695 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714696 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0414697 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614698 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314699 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0414700 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614701 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314702 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14703 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0414704
danakj1fd259a02016-04-16 03:17:0914705 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0414706
14707 // Start the first transaction to set up the SpdySession
14708 HttpRequestInfo request1;
14709 request1.method = "GET";
14710 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0414711 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014712 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0414713 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2014714 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414715
mmenke666a6fea2015-12-19 04:16:3314716 // This pause is a hack to avoid running into https://crbug.com/497228.
14717 data1.RunUntilPaused();
14718 base::RunLoop().RunUntilIdle();
14719 data1.Resume();
robpercival214763f2016-07-01 23:27:0114720 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0414721 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14722
[email protected]f6c63db52013-02-02 00:35:2214723 LoadTimingInfo load_timing_info1;
14724 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
14725 TestLoadTimingNotReusedWithPac(load_timing_info1,
14726 CONNECT_TIMING_HAS_SSL_TIMES);
14727
mmenke666a6fea2015-12-19 04:16:3314728 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0414729 HttpRequestInfo request2;
14730 request2.method = "GET";
14731 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0414732 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014733 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0414734 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2014735 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0414736
mmenke666a6fea2015-12-19 04:16:3314737 // This pause is a hack to avoid running into https://crbug.com/497228.
14738 data1.RunUntilPaused();
14739 base::RunLoop().RunUntilIdle();
14740 data1.Resume();
robpercival214763f2016-07-01 23:27:0114741 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3314742
[email protected]8450d722012-07-02 19:14:0414743 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214744
14745 LoadTimingInfo load_timing_info2;
14746 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14747 // The established SPDY sessions is considered reused by the HTTP request.
14748 TestLoadTimingReusedWithPac(load_timing_info2);
14749 // HTTP requests over a SPDY session should have a different connection
14750 // socket_log_id than requests over a tunnel.
14751 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414752}
14753
[email protected]2d88e7d2012-07-19 17:55:1714754// Test that in the case where we have a SPDY session to a SPDY proxy
14755// that we do not pool other origins that resolve to the same IP when
14756// the certificate does not match the new origin.
14757// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0114758TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314759 const std::string url1 = "http://www.example.org/";
14760 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714761 const std::string ip_addr = "1.2.3.4";
14762
rdsmithebb50aa2015-11-12 03:44:3814763 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0114764 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3814765
[email protected]2d88e7d2012-07-19 17:55:1714766 // SPDY GET for HTTP URL (through SPDY proxy)
bnc086b39e12016-06-24 13:05:2614767 SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2314768 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncdf80d44fd2016-07-15 20:27:4114769 SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1514770 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714771
14772 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4114773 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1714774 };
14775
bnc42331402016-07-25 13:36:1514776 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114777 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714778 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4114779 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
14780 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714781 };
14782
mmenke666a6fea2015-12-19 04:16:3314783 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14784 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214785 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914786 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714787 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14788 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314789 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714790
14791 // SPDY GET for HTTPS URL (direct)
bncdf80d44fd2016-07-15 20:27:4114792 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914793 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714794
14795 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114796 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1714797 };
14798
bnc42331402016-07-25 13:36:1514799 SpdySerializedFrame resp2(spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114800 SpdySerializedFrame body2(spdy_util_secure.ConstructSpdyDataFrame(1, true));
14801 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3314802 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714803
mmenke666a6fea2015-12-19 04:16:3314804 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14805 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714806 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314807 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714808
14809 // Set up a proxy config that sends HTTP requests to a proxy, and
14810 // all others direct.
14811 ProxyConfig proxy_config;
14812 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Jeremy Roman0579ed62017-08-29 15:56:1914813 session_deps_.proxy_service = std::make_unique<ProxyService>(
14814 std::make_unique<ProxyConfigServiceFixed>(proxy_config), nullptr,
bnc87dcefc2017-05-25 12:47:5814815 nullptr);
[email protected]2d88e7d2012-07-19 17:55:1714816
bncce36dca22015-04-21 22:11:2314817 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3614818 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1714819 // Load a valid cert. Note, that this does not need to
14820 // be valid for proxy because the MockSSLClientSocket does
14821 // not actually verify it. But SpdySession will use this
14822 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314823 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214824 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314825 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14826 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714827
14828 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3614829 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3314830 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14831 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714832
Jeremy Roman0579ed62017-08-29 15:56:1914833 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2314834 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714835 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714836
danakj1fd259a02016-04-16 03:17:0914837 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714838
14839 // Start the first transaction to set up the SpdySession
14840 HttpRequestInfo request1;
14841 request1.method = "GET";
14842 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714843 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014844 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714845 TestCompletionCallback callback1;
14846 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014847 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3314848 // This pause is a hack to avoid running into https://crbug.com/497228.
14849 data1.RunUntilPaused();
14850 base::RunLoop().RunUntilIdle();
14851 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714852
robpercival214763f2016-07-01 23:27:0114853 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714854 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14855
14856 // Now, start the HTTP request
14857 HttpRequestInfo request2;
14858 request2.method = "GET";
14859 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714860 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014861 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714862 TestCompletionCallback callback2;
14863 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014864 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5514865 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714866
14867 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0114868 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1714869 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14870}
14871
[email protected]85f97342013-04-17 06:12:2414872// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14873// error) in SPDY session, removes the socket from pool and closes the SPDY
14874// session. Verify that new url's from the same HttpNetworkSession (and a new
14875// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0114876TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314877 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414878
14879 MockRead reads1[] = {
14880 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14881 };
14882
mmenke11eb5152015-06-09 14:50:5014883 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414884
bncdf80d44fd2016-07-15 20:27:4114885 SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4914886 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414887 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4114888 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2414889 };
14890
bnc42331402016-07-25 13:36:1514891 SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114892 SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414893 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4114894 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
14895 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2414896 };
14897
mmenke11eb5152015-06-09 14:50:5014898 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14899 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414900
[email protected]85f97342013-04-17 06:12:2414901 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614902 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014903 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14904 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414905
14906 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614907 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5014908 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14909 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414910
danakj1fd259a02016-04-16 03:17:0914911 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014912 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414913
14914 // Start the first transaction to set up the SpdySession and verify that
14915 // connection was closed.
14916 HttpRequestInfo request1;
14917 request1.method = "GET";
14918 request1.url = GURL(https_url);
14919 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014920 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414921 TestCompletionCallback callback1;
14922 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014923 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0114924 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2414925
14926 // Now, start the second request and make sure it succeeds.
14927 HttpRequestInfo request2;
14928 request2.method = "GET";
14929 request2.url = GURL(https_url);
14930 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014931 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414932 TestCompletionCallback callback2;
14933 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2014934 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2414935
robpercival214763f2016-07-01 23:27:0114936 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2414937 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14938}
14939
bncd16676a2016-07-20 16:23:0114940TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314941 ClientSocketPoolManager::set_max_sockets_per_group(
14942 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14943 ClientSocketPoolManager::set_max_sockets_per_pool(
14944 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14945
14946 // Use two different hosts with different IPs so they don't get pooled.
14947 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14948 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914949 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314950
14951 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614952 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314953 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614954 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0314955 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14956 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14957
bncdf80d44fd2016-07-15 20:27:4114958 SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914959 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314960 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114961 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314962 };
bnc42331402016-07-25 13:36:1514963 SpdySerializedFrame host1_resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114964 SpdySerializedFrame host1_resp_body(
14965 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314966 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114967 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914968 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314969 };
14970
rdsmithebb50aa2015-11-12 03:44:3814971 // Use a separate test instance for the separate SpdySession that will be
14972 // created.
bncd16676a2016-07-20 16:23:0114973 SpdyTestUtil spdy_util_2;
Jeremy Roman0579ed62017-08-29 15:56:1914974 auto spdy1_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5814975 spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14976 arraysize(spdy1_writes));
[email protected]483fa202013-05-14 01:07:0314977 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14978
bncdf80d44fd2016-07-15 20:27:4114979 SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4914980 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314981 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114982 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314983 };
bnc42331402016-07-25 13:36:1514984 SpdySerializedFrame host2_resp(spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
bncdf80d44fd2016-07-15 20:27:4114985 SpdySerializedFrame host2_resp_body(
14986 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314987 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114988 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5914989 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314990 };
14991
Jeremy Roman0579ed62017-08-29 15:56:1914992 auto spdy2_data = std::make_unique<SequencedSocketData>(
bnc87dcefc2017-05-25 12:47:5814993 spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14994 arraysize(spdy2_writes));
[email protected]483fa202013-05-14 01:07:0314995 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14996
14997 MockWrite http_write[] = {
14998 MockWrite("GET / HTTP/1.1\r\n"
14999 "Host: www.a.com\r\n"
15000 "Connection: keep-alive\r\n\r\n"),
15001 };
15002
15003 MockRead http_read[] = {
15004 MockRead("HTTP/1.1 200 OK\r\n"),
15005 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15006 MockRead("Content-Length: 6\r\n\r\n"),
15007 MockRead("hello!"),
15008 };
15009 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
15010 http_write, arraysize(http_write));
15011 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15012
15013 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4015014 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5315015 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0315016 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615017 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315018
15019 TestCompletionCallback callback;
15020 HttpRequestInfo request1;
15021 request1.method = "GET";
15022 request1.url = GURL("https://www.a.com/");
15023 request1.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815024 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915025 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315026
tfarina42834112016-09-22 13:38:2015027 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115028 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15029 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315030
15031 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215032 ASSERT_TRUE(response);
15033 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215034 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315035 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215036 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315037
15038 std::string response_data;
robpercival214763f2016-07-01 23:27:0115039 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315040 EXPECT_EQ("hello!", response_data);
15041 trans.reset();
15042 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615043 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315044
15045 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4015046 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5315047 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0315048 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615049 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315050 HttpRequestInfo request2;
15051 request2.method = "GET";
15052 request2.url = GURL("https://www.b.com/");
15053 request2.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815054 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915055 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315056
tfarina42834112016-09-22 13:38:2015057 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115058 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15059 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315060
15061 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215062 ASSERT_TRUE(response);
15063 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215064 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315065 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215066 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115067 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315068 EXPECT_EQ("hello!", response_data);
15069 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615070 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315071 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615072 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315073
15074 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4015075 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5315076 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0315077 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615078 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315079 HttpRequestInfo request3;
15080 request3.method = "GET";
15081 request3.url = GURL("http://www.a.com/");
15082 request3.load_flags = 0;
bnc87dcefc2017-05-25 12:47:5815083 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915084 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315085
tfarina42834112016-09-22 13:38:2015086 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115087 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15088 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315089
15090 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215091 ASSERT_TRUE(response);
15092 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315093 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15094 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215095 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115096 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315097 EXPECT_EQ("hello!", response_data);
15098 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615099 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315100 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615101 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315102}
15103
bncd16676a2016-07-20 16:23:0115104TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415105 HttpRequestInfo request;
15106 request.method = "GET";
bncce36dca22015-04-21 22:11:2315107 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415108
danakj1fd259a02016-04-16 03:17:0915109 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615110 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415111
ttuttled9dbc652015-09-29 20:00:5915112 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415113 StaticSocketDataProvider data;
15114 data.set_connect_data(mock_connect);
15115 session_deps_.socket_factory->AddSocketDataProvider(&data);
15116
15117 TestCompletionCallback callback;
15118
tfarina42834112016-09-22 13:38:2015119 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115120 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415121
15122 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115123 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415124
[email protected]79e1fd62013-06-20 06:50:0415125 // We don't care whether this succeeds or fails, but it shouldn't crash.
15126 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615127 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715128
15129 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615130 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715131 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115132 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915133
15134 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615135 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915136 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415137}
15138
bncd16676a2016-07-20 16:23:0115139TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415140 HttpRequestInfo request;
15141 request.method = "GET";
bncce36dca22015-04-21 22:11:2315142 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415143
danakj1fd259a02016-04-16 03:17:0915144 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615145 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415146
ttuttled9dbc652015-09-29 20:00:5915147 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415148 StaticSocketDataProvider data;
15149 data.set_connect_data(mock_connect);
15150 session_deps_.socket_factory->AddSocketDataProvider(&data);
15151
15152 TestCompletionCallback callback;
15153
tfarina42834112016-09-22 13:38:2015154 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115155 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415156
15157 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115158 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415159
[email protected]79e1fd62013-06-20 06:50:0415160 // We don't care whether this succeeds or fails, but it shouldn't crash.
15161 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615162 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715163
15164 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615165 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715166 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115167 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915168
15169 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615170 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915171 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415172}
15173
bncd16676a2016-07-20 16:23:0115174TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415175 HttpRequestInfo request;
15176 request.method = "GET";
bncce36dca22015-04-21 22:11:2315177 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415178
danakj1fd259a02016-04-16 03:17:0915179 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615180 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415181
15182 MockWrite data_writes[] = {
15183 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15184 };
15185 MockRead data_reads[] = {
15186 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15187 };
15188
15189 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15190 data_writes, arraysize(data_writes));
15191 session_deps_.socket_factory->AddSocketDataProvider(&data);
15192
15193 TestCompletionCallback callback;
15194
tfarina42834112016-09-22 13:38:2015195 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115196 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415197
15198 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115199 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415200
[email protected]79e1fd62013-06-20 06:50:0415201 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615202 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415203 EXPECT_TRUE(request_headers.HasHeader("Host"));
15204}
15205
bncd16676a2016-07-20 16:23:0115206TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415207 HttpRequestInfo request;
15208 request.method = "GET";
bncce36dca22015-04-21 22:11:2315209 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415210
danakj1fd259a02016-04-16 03:17:0915211 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615212 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415213
15214 MockWrite data_writes[] = {
15215 MockWrite(ASYNC, ERR_CONNECTION_RESET),
15216 };
15217 MockRead data_reads[] = {
15218 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15219 };
15220
15221 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15222 data_writes, arraysize(data_writes));
15223 session_deps_.socket_factory->AddSocketDataProvider(&data);
15224
15225 TestCompletionCallback callback;
15226
tfarina42834112016-09-22 13:38:2015227 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115228 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415229
15230 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115231 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415232
[email protected]79e1fd62013-06-20 06:50:0415233 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615234 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415235 EXPECT_TRUE(request_headers.HasHeader("Host"));
15236}
15237
bncd16676a2016-07-20 16:23:0115238TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415239 HttpRequestInfo request;
15240 request.method = "GET";
bncce36dca22015-04-21 22:11:2315241 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415242
danakj1fd259a02016-04-16 03:17:0915243 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615244 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415245
15246 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315247 MockWrite(
15248 "GET / HTTP/1.1\r\n"
15249 "Host: www.example.org\r\n"
15250 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415251 };
15252 MockRead data_reads[] = {
15253 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
15254 };
15255
15256 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15257 data_writes, arraysize(data_writes));
15258 session_deps_.socket_factory->AddSocketDataProvider(&data);
15259
15260 TestCompletionCallback callback;
15261
tfarina42834112016-09-22 13:38:2015262 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415264
15265 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115266 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415267
[email protected]79e1fd62013-06-20 06:50:0415268 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615269 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415270 EXPECT_TRUE(request_headers.HasHeader("Host"));
15271}
15272
bncd16676a2016-07-20 16:23:0115273TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0415274 HttpRequestInfo request;
15275 request.method = "GET";
bncce36dca22015-04-21 22:11:2315276 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415277
danakj1fd259a02016-04-16 03:17:0915278 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615279 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415280
15281 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315282 MockWrite(
15283 "GET / HTTP/1.1\r\n"
15284 "Host: www.example.org\r\n"
15285 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415286 };
15287 MockRead data_reads[] = {
15288 MockRead(ASYNC, ERR_CONNECTION_RESET),
15289 };
15290
15291 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15292 data_writes, arraysize(data_writes));
15293 session_deps_.socket_factory->AddSocketDataProvider(&data);
15294
15295 TestCompletionCallback callback;
15296
tfarina42834112016-09-22 13:38:2015297 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115298 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415299
15300 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115301 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415302
[email protected]79e1fd62013-06-20 06:50:0415303 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615304 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415305 EXPECT_TRUE(request_headers.HasHeader("Host"));
15306}
15307
bncd16676a2016-07-20 16:23:0115308TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0415309 HttpRequestInfo request;
15310 request.method = "GET";
bncce36dca22015-04-21 22:11:2315311 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0415312 request.extra_headers.SetHeader("X-Foo", "bar");
15313
danakj1fd259a02016-04-16 03:17:0915314 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615315 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415316
15317 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2315318 MockWrite(
15319 "GET / HTTP/1.1\r\n"
15320 "Host: www.example.org\r\n"
15321 "Connection: keep-alive\r\n"
15322 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0415323 };
15324 MockRead data_reads[] = {
15325 MockRead("HTTP/1.1 200 OK\r\n"
15326 "Content-Length: 5\r\n\r\n"
15327 "hello"),
15328 MockRead(ASYNC, ERR_UNEXPECTED),
15329 };
15330
15331 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
15332 data_writes, arraysize(data_writes));
15333 session_deps_.socket_factory->AddSocketDataProvider(&data);
15334
15335 TestCompletionCallback callback;
15336
tfarina42834112016-09-22 13:38:2015337 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115338 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415339
15340 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115341 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0415342
15343 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615344 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415345 std::string foo;
15346 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
15347 EXPECT_EQ("bar", foo);
15348}
15349
[email protected]bf828982013-08-14 18:01:4715350namespace {
15351
yhiranoa7e05bb2014-11-06 05:40:3915352// Fake HttpStream that simply records calls to SetPriority().
15353class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0315354 public base::SupportsWeakPtr<FakeStream> {
15355 public:
15356 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2015357 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0315358
15359 RequestPriority priority() const { return priority_; }
15360
dchengb03027d2014-10-21 12:00:2015361 int InitializeStream(const HttpRequestInfo* request_info,
15362 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015363 const NetLogWithSource& net_log,
dchengb03027d2014-10-21 12:00:2015364 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315365 return ERR_IO_PENDING;
15366 }
15367
dchengb03027d2014-10-21 12:00:2015368 int SendRequest(const HttpRequestHeaders& request_headers,
15369 HttpResponseInfo* response,
15370 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315371 ADD_FAILURE();
15372 return ERR_UNEXPECTED;
15373 }
15374
dchengb03027d2014-10-21 12:00:2015375 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315376 ADD_FAILURE();
15377 return ERR_UNEXPECTED;
15378 }
15379
dchengb03027d2014-10-21 12:00:2015380 int ReadResponseBody(IOBuffer* buf,
15381 int buf_len,
15382 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0315383 ADD_FAILURE();
15384 return ERR_UNEXPECTED;
15385 }
15386
dchengb03027d2014-10-21 12:00:2015387 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0315388
dchengb03027d2014-10-21 12:00:2015389 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0315390 ADD_FAILURE();
15391 return false;
15392 }
15393
dchengb03027d2014-10-21 12:00:2015394 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0315395 ADD_FAILURE();
15396 return false;
15397 }
15398
dchengb03027d2014-10-21 12:00:2015399 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315400
mmenkebd84c392015-09-02 14:12:3415401 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0315402
sclittle4de1bab92015-09-22 21:28:2415403 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5915404 ADD_FAILURE();
15405 return 0;
15406 }
15407
sclittlebe1ccf62015-09-02 19:40:3615408 int64_t GetTotalSentBytes() const override {
15409 ADD_FAILURE();
15410 return 0;
15411 }
15412
dchengb03027d2014-10-21 12:00:2015413 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0315414 ADD_FAILURE();
15415 return false;
15416 }
15417
rchcd379012017-04-12 21:53:3215418 bool GetAlternativeService(
15419 AlternativeService* alternative_service) const override {
15420 ADD_FAILURE();
15421 return false;
15422 }
15423
dchengb03027d2014-10-21 12:00:2015424 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
15425
15426 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0315427 ADD_FAILURE();
15428 }
15429
ttuttled9dbc652015-09-29 20:00:5915430 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15431
nharper78e6d2b2016-09-21 05:42:3515432 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15433 TokenBindingType tb_type,
15434 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415435 ADD_FAILURE();
15436 return ERR_NOT_IMPLEMENTED;
15437 }
15438
dchengb03027d2014-10-21 12:00:2015439 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0315440
zhongyica364fbb2015-12-12 03:39:1215441 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15442
dchengb03027d2014-10-21 12:00:2015443 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0315444
yhiranoa7e05bb2014-11-06 05:40:3915445 HttpStream* RenewStreamForAuth() override { return NULL; }
15446
Andrey Kosyakov83a6eee2017-08-14 19:20:0415447 void SetRequestHeadersCallback(RequestHeadersCallback callback) override {}
15448
[email protected]e86839fd2013-08-14 18:29:0315449 private:
15450 RequestPriority priority_;
15451
15452 DISALLOW_COPY_AND_ASSIGN(FakeStream);
15453};
15454
15455// Fake HttpStreamRequest that simply records calls to SetPriority()
15456// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4715457class FakeStreamRequest : public HttpStreamRequest,
15458 public base::SupportsWeakPtr<FakeStreamRequest> {
15459 public:
[email protected]e86839fd2013-08-14 18:29:0315460 FakeStreamRequest(RequestPriority priority,
15461 HttpStreamRequest::Delegate* delegate)
15462 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4415463 delegate_(delegate),
15464 websocket_stream_create_helper_(NULL) {}
15465
15466 FakeStreamRequest(RequestPriority priority,
15467 HttpStreamRequest::Delegate* delegate,
15468 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
15469 : priority_(priority),
15470 delegate_(delegate),
15471 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0315472
dchengb03027d2014-10-21 12:00:2015473 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4715474
15475 RequestPriority priority() const { return priority_; }
15476
[email protected]831e4a32013-11-14 02:14:4415477 const WebSocketHandshakeStreamBase::CreateHelper*
15478 websocket_stream_create_helper() const {
15479 return websocket_stream_create_helper_;
15480 }
15481
[email protected]e86839fd2013-08-14 18:29:0315482 // Create a new FakeStream and pass it to the request's
15483 // delegate. Returns a weak pointer to the FakeStream.
15484 base::WeakPtr<FakeStream> FinishStreamRequest() {
Jeremy Roman0579ed62017-08-29 15:56:1915485 auto fake_stream = std::make_unique<FakeStream>(priority_);
[email protected]e86839fd2013-08-14 18:29:0315486 // Do this before calling OnStreamReady() as OnStreamReady() may
15487 // immediately delete |fake_stream|.
15488 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
bnc5029f4632017-06-08 16:19:0015489 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), std::move(fake_stream));
[email protected]e86839fd2013-08-14 18:29:0315490 return weak_stream;
15491 }
15492
asanka681f02d2017-02-22 17:06:3915493 int RestartTunnelWithProxyAuth() override {
[email protected]bf828982013-08-14 18:01:4715494 ADD_FAILURE();
15495 return ERR_UNEXPECTED;
15496 }
15497
dchengb03027d2014-10-21 12:00:2015498 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4715499 ADD_FAILURE();
15500 return LoadState();
15501 }
15502
dchengb03027d2014-10-21 12:00:2015503 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4715504
bnc94c92842016-09-21 15:22:5215505 bool was_alpn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715506
bnc6227b26e2016-08-12 02:00:4315507 NextProto negotiated_protocol() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4715508
dchengb03027d2014-10-21 12:00:2015509 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4715510
ttuttle1f2d7e92015-04-28 16:17:4715511 const ConnectionAttempts& connection_attempts() const override {
15512 static ConnectionAttempts no_attempts;
15513 return no_attempts;
15514 }
15515
[email protected]bf828982013-08-14 18:01:4715516 private:
15517 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0315518 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4415519 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4715520
15521 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
15522};
15523
15524// Fake HttpStreamFactory that vends FakeStreamRequests.
15525class FakeStreamFactory : public HttpStreamFactory {
15526 public:
15527 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2015528 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4715529
15530 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
15531 // RequestStream() (which may be NULL if it was destroyed already).
15532 base::WeakPtr<FakeStreamRequest> last_stream_request() {
15533 return last_stream_request_;
15534 }
15535
xunjieli96f2a402017-06-05 17:24:2715536 std::unique_ptr<HttpStreamRequest> RequestStream(
15537 const HttpRequestInfo& info,
15538 RequestPriority priority,
15539 const SSLConfig& server_ssl_config,
15540 const SSLConfig& proxy_ssl_config,
15541 HttpStreamRequest::Delegate* delegate,
15542 bool enable_ip_based_pooling,
15543 bool enable_alternative_services,
15544 const NetLogWithSource& net_log) override {
Jeremy Roman0579ed62017-08-29 15:56:1915545 auto fake_request = std::make_unique<FakeStreamRequest>(priority, delegate);
[email protected]bf828982013-08-14 18:01:4715546 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715547 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715548 }
15549
xunjieli96f2a402017-06-05 17:24:2715550 std::unique_ptr<HttpStreamRequest> RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0815551 const HttpRequestInfo& info,
15552 RequestPriority priority,
15553 const SSLConfig& server_ssl_config,
15554 const SSLConfig& proxy_ssl_config,
15555 HttpStreamRequest::Delegate* delegate,
bnc8016c1f2017-03-31 02:11:2915556 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615557 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015558 const NetLogWithSource& net_log) override {
xunjieli11834f02015-12-22 04:27:0815559 NOTREACHED();
15560 return nullptr;
15561 }
15562
xunjieli96f2a402017-06-05 17:24:2715563 std::unique_ptr<HttpStreamRequest> RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4715564 const HttpRequestInfo& info,
15565 RequestPriority priority,
15566 const SSLConfig& server_ssl_config,
15567 const SSLConfig& proxy_ssl_config,
15568 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4615569 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
bnc8016c1f2017-03-31 02:11:2915570 bool enable_ip_based_pooling,
bncaccd4962017-04-06 21:00:2615571 bool enable_alternative_services,
tfarina42834112016-09-22 13:38:2015572 const NetLogWithSource& net_log) override {
xunjieli96f2a402017-06-05 17:24:2715573 auto fake_request =
Jeremy Roman0579ed62017-08-29 15:56:1915574 std::make_unique<FakeStreamRequest>(priority, delegate, create_helper);
[email protected]831e4a32013-11-14 02:14:4415575 last_stream_request_ = fake_request->AsWeakPtr();
xunjieli96f2a402017-06-05 17:24:2715576 return std::move(fake_request);
[email protected]bf828982013-08-14 18:01:4715577 }
15578
dchengb03027d2014-10-21 12:00:2015579 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5915580 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4715581 ADD_FAILURE();
15582 }
15583
dchengb03027d2014-10-21 12:00:2015584 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4715585 ADD_FAILURE();
15586 return NULL;
15587 }
15588
xunjielif5267de2017-01-20 21:18:5715589 void DumpMemoryStats(base::trace_event::ProcessMemoryDump* pmd,
15590 const std::string& parent_absolute_name) const override {
15591 ADD_FAILURE();
15592 }
15593
[email protected]bf828982013-08-14 18:01:4715594 private:
15595 base::WeakPtr<FakeStreamRequest> last_stream_request_;
15596
15597 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
15598};
15599
Adam Rice425cf122015-01-19 06:18:2415600// TODO(ricea): Maybe unify this with the one in
15601// url_request_http_job_unittest.cc ?
15602class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
15603 public:
danakj1fd259a02016-04-16 03:17:0915604 FakeWebSocketBasicHandshakeStream(
15605 std::unique_ptr<ClientSocketHandle> connection,
15606 bool using_proxy)
mmenkea7da6da2016-09-01 21:56:5215607 : state_(std::move(connection), using_proxy, false) {}
Adam Rice425cf122015-01-19 06:18:2415608
15609 // Fake implementation of HttpStreamBase methods.
15610 // This ends up being quite "real" because this object has to really send data
15611 // on the mock socket. It might be easier to use the real implementation, but
15612 // the fact that the WebSocket code is not compiled on iOS makes that
15613 // difficult.
15614 int InitializeStream(const HttpRequestInfo* request_info,
15615 RequestPriority priority,
tfarina42834112016-09-22 13:38:2015616 const NetLogWithSource& net_log,
Adam Rice425cf122015-01-19 06:18:2415617 const CompletionCallback& callback) override {
15618 state_.Initialize(request_info, priority, net_log, callback);
15619 return OK;
15620 }
15621
15622 int SendRequest(const HttpRequestHeaders& request_headers,
15623 HttpResponseInfo* response,
15624 const CompletionCallback& callback) override {
15625 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
15626 response, callback);
15627 }
15628
15629 int ReadResponseHeaders(const CompletionCallback& callback) override {
15630 return parser()->ReadResponseHeaders(callback);
15631 }
15632
15633 int ReadResponseBody(IOBuffer* buf,
15634 int buf_len,
15635 const CompletionCallback& callback) override {
15636 NOTREACHED();
15637 return ERR_IO_PENDING;
15638 }
15639
15640 void Close(bool not_reusable) override {
15641 if (parser())
15642 parser()->Close(true);
15643 }
15644
15645 bool IsResponseBodyComplete() const override {
15646 NOTREACHED();
15647 return false;
15648 }
15649
Adam Rice425cf122015-01-19 06:18:2415650 bool IsConnectionReused() const override {
15651 NOTREACHED();
15652 return false;
15653 }
15654 void SetConnectionReused() override { NOTREACHED(); }
15655
mmenkebd84c392015-09-02 14:12:3415656 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2415657
sclittle4de1bab92015-09-22 21:28:2415658 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2415659 NOTREACHED();
15660 return 0;
15661 }
15662
sclittlebe1ccf62015-09-02 19:40:3615663 int64_t GetTotalSentBytes() const override {
15664 NOTREACHED();
15665 return 0;
15666 }
15667
Adam Rice425cf122015-01-19 06:18:2415668 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
15669 NOTREACHED();
15670 return false;
15671 }
15672
rchcd379012017-04-12 21:53:3215673 bool GetAlternativeService(
15674 AlternativeService* alternative_service) const override {
15675 ADD_FAILURE();
15676 return false;
15677 }
15678
Adam Ricecb76ac62015-02-20 05:33:2515679 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2415680
15681 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
15682 NOTREACHED();
15683 }
15684
ttuttled9dbc652015-09-29 20:00:5915685 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
15686
nharper78e6d2b2016-09-21 05:42:3515687 Error GetTokenBindingSignature(crypto::ECPrivateKey* key,
15688 TokenBindingType tb_type,
15689 std::vector<uint8_t>* out) override {
nharperb7441ef2016-01-25 23:54:1415690 ADD_FAILURE();
15691 return ERR_NOT_IMPLEMENTED;
15692 }
15693
Adam Rice425cf122015-01-19 06:18:2415694 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
15695
zhongyica364fbb2015-12-12 03:39:1215696 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
15697
Adam Rice425cf122015-01-19 06:18:2415698 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
15699
Adam Rice425cf122015-01-19 06:18:2415700 HttpStream* RenewStreamForAuth() override {
15701 NOTREACHED();
15702 return nullptr;
15703 }
15704
15705 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0915706 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2415707 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915708 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2415709 }
15710
15711 private:
15712 HttpStreamParser* parser() const { return state_.parser(); }
15713 HttpBasicState state_;
15714
15715 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
15716};
15717
[email protected]831e4a32013-11-14 02:14:4415718// TODO(yhirano): Split this class out into a net/websockets file, if it is
15719// worth doing.
15720class FakeWebSocketStreamCreateHelper :
15721 public WebSocketHandshakeStreamBase::CreateHelper {
15722 public:
bnc615cf2f2017-05-19 18:53:2615723 std::unique_ptr<WebSocketHandshakeStreamBase> CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0915724 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1315725 bool using_proxy) override {
Jeremy Roman0579ed62017-08-29 15:56:1915726 return std::make_unique<FakeWebSocketBasicHandshakeStream>(
bnc615cf2f2017-05-19 18:53:2615727 std::move(connection), using_proxy);
[email protected]831e4a32013-11-14 02:14:4415728 }
15729
dchengb03027d2014-10-21 12:00:2015730 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415731
danakj1fd259a02016-04-16 03:17:0915732 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415733 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915734 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415735 }
15736};
15737
[email protected]bf828982013-08-14 18:01:4715738} // namespace
15739
15740// Make sure that HttpNetworkTransaction passes on its priority to its
15741// stream request on start.
bncd16676a2016-07-20 16:23:0115742TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915743 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215744 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715745 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915746 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715747
krasinc06a72a2016-12-21 03:42:4615748 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115749 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715750
wezca1070932016-05-26 20:30:5215751 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715752
[email protected]bf828982013-08-14 18:01:4715753 TestCompletionCallback callback;
15754 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015755 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715756
15757 base::WeakPtr<FakeStreamRequest> fake_request =
15758 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215759 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715760 EXPECT_EQ(LOW, fake_request->priority());
15761}
15762
15763// Make sure that HttpNetworkTransaction passes on its priority
15764// updates to its stream request.
bncd16676a2016-07-20 16:23:0115765TEST_F(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215767 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715768 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915769 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715770
krasinc06a72a2016-12-21 03:42:4615771 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115772 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715773
[email protected]bf828982013-08-14 18:01:4715774 TestCompletionCallback callback;
15775 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015776 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]bf828982013-08-14 18:01:4715777
15778 base::WeakPtr<FakeStreamRequest> fake_request =
15779 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215780 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715781 EXPECT_EQ(LOW, fake_request->priority());
15782
15783 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215784 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715785 EXPECT_EQ(LOWEST, fake_request->priority());
15786}
15787
[email protected]e86839fd2013-08-14 18:29:0315788// Make sure that HttpNetworkTransaction passes on its priority
15789// updates to its stream.
bncd16676a2016-07-20 16:23:0115790TEST_F(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915791 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215792 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315793 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915794 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315795
krasinc06a72a2016-12-21 03:42:4615796 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115797 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315798
[email protected]e86839fd2013-08-14 18:29:0315799 TestCompletionCallback callback;
15800 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015801 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]e86839fd2013-08-14 18:29:0315802
15803 base::WeakPtr<FakeStreamRequest> fake_request =
15804 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215805 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315806 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215807 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315808 EXPECT_EQ(LOW, fake_stream->priority());
15809
15810 trans.SetPriority(LOWEST);
15811 EXPECT_EQ(LOWEST, fake_stream->priority());
15812}
15813
bncd16676a2016-07-20 16:23:0115814TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
[email protected]831e4a32013-11-14 02:14:4415815 // The same logic needs to be tested for both ws: and wss: schemes, but this
15816 // test is already parameterised on NextProto, so it uses a loop to verify
15817 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315818 std::string test_cases[] = {"ws://www.example.org/",
15819 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415820 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915821 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215822 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415823 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15824 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315825 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915826 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415827
krasinc06a72a2016-12-21 03:42:4615828 HttpRequestInfo request;
dcheng48459ac22014-08-26 00:46:4115829 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415830 trans.SetWebSocketHandshakeStreamCreateHelper(
15831 &websocket_stream_create_helper);
15832
[email protected]831e4a32013-11-14 02:14:4415833 TestCompletionCallback callback;
15834 request.method = "GET";
15835 request.url = GURL(test_cases[i]);
15836
15837 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015838 trans.Start(&request, callback.callback(), NetLogWithSource()));
[email protected]831e4a32013-11-14 02:14:4415839
15840 base::WeakPtr<FakeStreamRequest> fake_request =
15841 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215842 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415843 EXPECT_EQ(&websocket_stream_create_helper,
15844 fake_request->websocket_stream_create_helper());
15845 }
15846}
15847
[email protected]043b68c82013-08-22 23:41:5215848// Tests that when a used socket is returned to the SSL socket pool, it's closed
15849// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115850TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5215851 ClientSocketPoolManager::set_max_sockets_per_group(
15852 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15853 ClientSocketPoolManager::set_max_sockets_per_pool(
15854 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15855
15856 // Set up SSL request.
15857
15858 HttpRequestInfo ssl_request;
15859 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315860 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215861
15862 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315863 MockWrite(
15864 "GET / HTTP/1.1\r\n"
15865 "Host: www.example.org\r\n"
15866 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215867 };
15868 MockRead ssl_reads[] = {
15869 MockRead("HTTP/1.1 200 OK\r\n"),
15870 MockRead("Content-Length: 11\r\n\r\n"),
15871 MockRead("hello world"),
15872 MockRead(SYNCHRONOUS, OK),
15873 };
15874 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15875 ssl_writes, arraysize(ssl_writes));
15876 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15877
15878 SSLSocketDataProvider ssl(ASYNC, OK);
15879 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15880
15881 // Set up HTTP request.
15882
15883 HttpRequestInfo http_request;
15884 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315885 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215886
15887 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315888 MockWrite(
15889 "GET / HTTP/1.1\r\n"
15890 "Host: www.example.org\r\n"
15891 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215892 };
15893 MockRead http_reads[] = {
15894 MockRead("HTTP/1.1 200 OK\r\n"),
15895 MockRead("Content-Length: 7\r\n\r\n"),
15896 MockRead("falafel"),
15897 MockRead(SYNCHRONOUS, OK),
15898 };
15899 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15900 http_writes, arraysize(http_writes));
15901 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15902
danakj1fd259a02016-04-16 03:17:0915903 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215904
15905 // Start the SSL request.
15906 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1615907 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015908 ASSERT_EQ(ERR_IO_PENDING,
15909 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
15910 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5215911
15912 // Start the HTTP request. Pool should stall.
15913 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615914 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015915 ASSERT_EQ(ERR_IO_PENDING,
15916 http_trans.Start(&http_request, http_callback.callback(),
15917 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115918 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215919
15920 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0115921 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5215922 std::string response_data;
bnc691fda62016-08-12 00:43:1615923 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215924 EXPECT_EQ("hello world", response_data);
15925
15926 // The SSL socket should automatically be closed, so the HTTP request can
15927 // start.
dcheng48459ac22014-08-26 00:46:4115928 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15929 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215930
15931 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0115932 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1615933 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5215934 EXPECT_EQ("falafel", response_data);
15935
dcheng48459ac22014-08-26 00:46:4115936 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215937}
15938
15939// Tests that when a SSL connection is established but there's no corresponding
15940// request that needs it, the new socket is closed if the transport socket pool
15941// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0115942TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5215943 ClientSocketPoolManager::set_max_sockets_per_group(
15944 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15945 ClientSocketPoolManager::set_max_sockets_per_pool(
15946 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15947
15948 // Set up an ssl request.
15949
15950 HttpRequestInfo ssl_request;
15951 ssl_request.method = "GET";
15952 ssl_request.url = GURL("https://www.foopy.com/");
15953
15954 // No data will be sent on the SSL socket.
15955 StaticSocketDataProvider ssl_data;
15956 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15957
15958 SSLSocketDataProvider ssl(ASYNC, OK);
15959 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15960
15961 // Set up HTTP request.
15962
15963 HttpRequestInfo http_request;
15964 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315965 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215966
15967 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315968 MockWrite(
15969 "GET / HTTP/1.1\r\n"
15970 "Host: www.example.org\r\n"
15971 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215972 };
15973 MockRead http_reads[] = {
15974 MockRead("HTTP/1.1 200 OK\r\n"),
15975 MockRead("Content-Length: 7\r\n\r\n"),
15976 MockRead("falafel"),
15977 MockRead(SYNCHRONOUS, OK),
15978 };
15979 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15980 http_writes, arraysize(http_writes));
15981 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15982
danakj1fd259a02016-04-16 03:17:0915983 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215984
15985 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15986 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915987 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915988 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115989 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215990
15991 // Start the HTTP request. Pool should stall.
15992 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1615993 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2015994 ASSERT_EQ(ERR_IO_PENDING,
15995 http_trans.Start(&http_request, http_callback.callback(),
15996 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4115997 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215998
15999 // The SSL connection will automatically be closed once the connection is
16000 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116001 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216002 std::string response_data;
bnc691fda62016-08-12 00:43:1616003 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216004 EXPECT_EQ("falafel", response_data);
16005
dcheng48459ac22014-08-26 00:46:4116006 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216007}
16008
bncd16676a2016-07-20 16:23:0116009TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916010 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216011 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916012 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216013 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416014
16015 HttpRequestInfo request;
16016 request.method = "POST";
16017 request.url = GURL("http://www.foo.com/");
16018 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416019
danakj1fd259a02016-04-16 03:17:0916020 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616021 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416022 // Send headers successfully, but get an error while sending the body.
16023 MockWrite data_writes[] = {
16024 MockWrite("POST / HTTP/1.1\r\n"
16025 "Host: www.foo.com\r\n"
16026 "Connection: keep-alive\r\n"
16027 "Content-Length: 3\r\n\r\n"),
16028 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16029 };
16030
16031 MockRead data_reads[] = {
16032 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16033 MockRead("hello world"),
16034 MockRead(SYNCHRONOUS, OK),
16035 };
16036 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16037 arraysize(data_writes));
16038 session_deps_.socket_factory->AddSocketDataProvider(&data);
16039
16040 TestCompletionCallback callback;
16041
tfarina42834112016-09-22 13:38:2016042 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116043 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416044
16045 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116046 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416047
bnc691fda62016-08-12 00:43:1616048 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216049 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416050
wezca1070932016-05-26 20:30:5216051 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416052 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16053
16054 std::string response_data;
bnc691fda62016-08-12 00:43:1616055 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116056 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416057 EXPECT_EQ("hello world", response_data);
16058}
16059
16060// This test makes sure the retry logic doesn't trigger when reading an error
16061// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116062TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416063 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916064 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416065 MockWrite data_writes[] = {
16066 MockWrite("GET / HTTP/1.1\r\n"
16067 "Host: www.foo.com\r\n"
16068 "Connection: keep-alive\r\n\r\n"),
16069 MockWrite("POST / HTTP/1.1\r\n"
16070 "Host: www.foo.com\r\n"
16071 "Connection: keep-alive\r\n"
16072 "Content-Length: 3\r\n\r\n"),
16073 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16074 };
16075
16076 MockRead data_reads[] = {
16077 MockRead("HTTP/1.1 200 Peachy\r\n"
16078 "Content-Length: 14\r\n\r\n"),
16079 MockRead("first response"),
16080 MockRead("HTTP/1.1 400 Not OK\r\n"
16081 "Content-Length: 15\r\n\r\n"),
16082 MockRead("second response"),
16083 MockRead(SYNCHRONOUS, OK),
16084 };
16085 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16086 arraysize(data_writes));
16087 session_deps_.socket_factory->AddSocketDataProvider(&data);
16088
16089 TestCompletionCallback callback;
16090 HttpRequestInfo request1;
16091 request1.method = "GET";
16092 request1.url = GURL("http://www.foo.com/");
16093 request1.load_flags = 0;
16094
bnc87dcefc2017-05-25 12:47:5816095 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916096 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016097 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116098 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416099
16100 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116101 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416102
16103 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216104 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416105
wezca1070932016-05-26 20:30:5216106 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416107 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16108
16109 std::string response_data1;
16110 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116111 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416112 EXPECT_EQ("first response", response_data1);
16113 // Delete the transaction to release the socket back into the socket pool.
16114 trans1.reset();
16115
danakj1fd259a02016-04-16 03:17:0916116 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216117 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916118 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216119 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416120
16121 HttpRequestInfo request2;
16122 request2.method = "POST";
16123 request2.url = GURL("http://www.foo.com/");
16124 request2.upload_data_stream = &upload_data_stream;
16125 request2.load_flags = 0;
16126
bnc691fda62016-08-12 00:43:1616127 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016128 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116129 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416130
16131 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116132 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416133
bnc691fda62016-08-12 00:43:1616134 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216135 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416136
wezca1070932016-05-26 20:30:5216137 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416138 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16139
16140 std::string response_data2;
bnc691fda62016-08-12 00:43:1616141 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116142 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416143 EXPECT_EQ("second response", response_data2);
16144}
16145
bncd16676a2016-07-20 16:23:0116146TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416147 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916148 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216149 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916150 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216151 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416152
16153 HttpRequestInfo request;
16154 request.method = "POST";
16155 request.url = GURL("http://www.foo.com/");
16156 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416157
danakj1fd259a02016-04-16 03:17:0916158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616159 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416160 // Send headers successfully, but get an error while sending the body.
16161 MockWrite data_writes[] = {
16162 MockWrite("POST / HTTP/1.1\r\n"
16163 "Host: www.foo.com\r\n"
16164 "Connection: keep-alive\r\n"
16165 "Content-Length: 3\r\n\r\n"
16166 "fo"),
16167 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16168 };
16169
16170 MockRead data_reads[] = {
16171 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16172 MockRead("hello world"),
16173 MockRead(SYNCHRONOUS, OK),
16174 };
16175 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16176 arraysize(data_writes));
16177 session_deps_.socket_factory->AddSocketDataProvider(&data);
16178
16179 TestCompletionCallback callback;
16180
tfarina42834112016-09-22 13:38:2016181 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116182 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416183
16184 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116185 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416186
bnc691fda62016-08-12 00:43:1616187 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216188 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416189
wezca1070932016-05-26 20:30:5216190 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416191 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16192
16193 std::string response_data;
bnc691fda62016-08-12 00:43:1616194 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116195 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416196 EXPECT_EQ("hello world", response_data);
16197}
16198
16199// This tests the more common case than the previous test, where headers and
16200// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116201TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716202 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416203
16204 HttpRequestInfo request;
16205 request.method = "POST";
16206 request.url = GURL("http://www.foo.com/");
16207 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416208
danakj1fd259a02016-04-16 03:17:0916209 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616210 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416211 // Send headers successfully, but get an error while sending the body.
16212 MockWrite data_writes[] = {
16213 MockWrite("POST / HTTP/1.1\r\n"
16214 "Host: www.foo.com\r\n"
16215 "Connection: keep-alive\r\n"
16216 "Transfer-Encoding: chunked\r\n\r\n"),
16217 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16218 };
16219
16220 MockRead data_reads[] = {
16221 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16222 MockRead("hello world"),
16223 MockRead(SYNCHRONOUS, OK),
16224 };
16225 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16226 arraysize(data_writes));
16227 session_deps_.socket_factory->AddSocketDataProvider(&data);
16228
16229 TestCompletionCallback callback;
16230
tfarina42834112016-09-22 13:38:2016231 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116232 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416233 // Make sure the headers are sent before adding a chunk. This ensures that
16234 // they can't be merged with the body in a single send. Not currently
16235 // necessary since a chunked body is never merged with headers, but this makes
16236 // the test more future proof.
16237 base::RunLoop().RunUntilIdle();
16238
mmenkecbc2b712014-10-09 20:29:0716239 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416240
16241 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116242 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416243
bnc691fda62016-08-12 00:43:1616244 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216245 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416246
wezca1070932016-05-26 20:30:5216247 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416248 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16249
16250 std::string response_data;
bnc691fda62016-08-12 00:43:1616251 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116252 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416253 EXPECT_EQ("hello world", response_data);
16254}
16255
bncd16676a2016-07-20 16:23:0116256TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916257 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216258 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916259 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216260 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416261
16262 HttpRequestInfo request;
16263 request.method = "POST";
16264 request.url = GURL("http://www.foo.com/");
16265 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416266
danakj1fd259a02016-04-16 03:17:0916267 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616268 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416269
16270 MockWrite data_writes[] = {
16271 MockWrite("POST / HTTP/1.1\r\n"
16272 "Host: www.foo.com\r\n"
16273 "Connection: keep-alive\r\n"
16274 "Content-Length: 3\r\n\r\n"),
16275 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16276 };
16277
16278 MockRead data_reads[] = {
16279 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16280 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16281 MockRead("hello world"),
16282 MockRead(SYNCHRONOUS, OK),
16283 };
16284 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16285 arraysize(data_writes));
16286 session_deps_.socket_factory->AddSocketDataProvider(&data);
16287
16288 TestCompletionCallback callback;
16289
tfarina42834112016-09-22 13:38:2016290 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116291 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416292
16293 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116294 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416295
bnc691fda62016-08-12 00:43:1616296 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216297 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416298
wezca1070932016-05-26 20:30:5216299 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416300 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16301
16302 std::string response_data;
bnc691fda62016-08-12 00:43:1616303 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116304 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416305 EXPECT_EQ("hello world", response_data);
16306}
16307
bncd16676a2016-07-20 16:23:0116308TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916309 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216310 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916311 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216312 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416313
16314 HttpRequestInfo request;
16315 request.method = "POST";
16316 request.url = GURL("http://www.foo.com/");
16317 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416318
danakj1fd259a02016-04-16 03:17:0916319 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616320 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416321 // Send headers successfully, but get an error while sending the body.
16322 MockWrite data_writes[] = {
16323 MockWrite("POST / HTTP/1.1\r\n"
16324 "Host: www.foo.com\r\n"
16325 "Connection: keep-alive\r\n"
16326 "Content-Length: 3\r\n\r\n"),
16327 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16328 };
16329
16330 MockRead data_reads[] = {
16331 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16332 MockRead("hello world"),
16333 MockRead(SYNCHRONOUS, OK),
16334 };
16335 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16336 arraysize(data_writes));
16337 session_deps_.socket_factory->AddSocketDataProvider(&data);
16338
16339 TestCompletionCallback callback;
16340
tfarina42834112016-09-22 13:38:2016341 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116342 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416343
16344 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116345 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416346}
16347
bncd16676a2016-07-20 16:23:0116348TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416349 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916350 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216351 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916352 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216353 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416354
16355 HttpRequestInfo request;
16356 request.method = "POST";
16357 request.url = GURL("http://www.foo.com/");
16358 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416359
danakj1fd259a02016-04-16 03:17:0916360 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616361 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416362 // Send headers successfully, but get an error while sending the body.
16363 MockWrite data_writes[] = {
16364 MockWrite("POST / HTTP/1.1\r\n"
16365 "Host: www.foo.com\r\n"
16366 "Connection: keep-alive\r\n"
16367 "Content-Length: 3\r\n\r\n"),
16368 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16369 };
16370
16371 MockRead data_reads[] = {
16372 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16373 MockRead("HTTP/1.0 302 Redirect\r\n"),
16374 MockRead("Location: http://somewhere-else.com/\r\n"),
16375 MockRead("Content-Length: 0\r\n\r\n"),
16376 MockRead(SYNCHRONOUS, OK),
16377 };
16378 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16379 arraysize(data_writes));
16380 session_deps_.socket_factory->AddSocketDataProvider(&data);
16381
16382 TestCompletionCallback callback;
16383
tfarina42834112016-09-22 13:38:2016384 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116385 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416386
16387 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116388 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416389}
16390
bncd16676a2016-07-20 16:23:0116391TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916392 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216393 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916394 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216395 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416396
16397 HttpRequestInfo request;
16398 request.method = "POST";
16399 request.url = GURL("http://www.foo.com/");
16400 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416401
danakj1fd259a02016-04-16 03:17:0916402 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616403 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416404 // Send headers successfully, but get an error while sending the body.
16405 MockWrite data_writes[] = {
16406 MockWrite("POST / HTTP/1.1\r\n"
16407 "Host: www.foo.com\r\n"
16408 "Connection: keep-alive\r\n"
16409 "Content-Length: 3\r\n\r\n"),
16410 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16411 };
16412
16413 MockRead data_reads[] = {
16414 MockRead("HTTP 0.9 rocks!"),
16415 MockRead(SYNCHRONOUS, OK),
16416 };
16417 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16418 arraysize(data_writes));
16419 session_deps_.socket_factory->AddSocketDataProvider(&data);
16420
16421 TestCompletionCallback callback;
16422
tfarina42834112016-09-22 13:38:2016423 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116424 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416425
16426 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116427 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416428}
16429
bncd16676a2016-07-20 16:23:0116430TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916431 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216432 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916433 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216434 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416435
16436 HttpRequestInfo request;
16437 request.method = "POST";
16438 request.url = GURL("http://www.foo.com/");
16439 request.upload_data_stream = &upload_data_stream;
[email protected]02d74a02014-04-23 18:10:5416440
danakj1fd259a02016-04-16 03:17:0916441 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616442 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416443 // Send headers successfully, but get an error while sending the body.
16444 MockWrite data_writes[] = {
16445 MockWrite("POST / HTTP/1.1\r\n"
16446 "Host: www.foo.com\r\n"
16447 "Connection: keep-alive\r\n"
16448 "Content-Length: 3\r\n\r\n"),
16449 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16450 };
16451
16452 MockRead data_reads[] = {
16453 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16454 MockRead(SYNCHRONOUS, OK),
16455 };
16456 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16457 arraysize(data_writes));
16458 session_deps_.socket_factory->AddSocketDataProvider(&data);
16459
16460 TestCompletionCallback callback;
16461
tfarina42834112016-09-22 13:38:2016462 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416464
16465 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116466 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416467}
16468
Adam Rice425cf122015-01-19 06:18:2416469// Verify that proxy headers are not sent to the destination server when
16470// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116471TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416472 HttpRequestInfo request;
16473 request.method = "GET";
bncce36dca22015-04-21 22:11:2316474 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416475 AddWebSocketHeaders(&request.extra_headers);
16476
16477 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316478 session_deps_.proxy_service =
16479 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416480
danakj1fd259a02016-04-16 03:17:0916481 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416482
16483 // Since a proxy is configured, try to establish a tunnel.
16484 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716485 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16486 "Host: www.example.org:443\r\n"
16487 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416488
16489 // After calling trans->RestartWithAuth(), this is the request we should
16490 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716491 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16492 "Host: www.example.org:443\r\n"
16493 "Proxy-Connection: keep-alive\r\n"
16494 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416495
rsleevidb16bb02015-11-12 23:47:1716496 MockWrite("GET / HTTP/1.1\r\n"
16497 "Host: www.example.org\r\n"
16498 "Connection: Upgrade\r\n"
16499 "Upgrade: websocket\r\n"
16500 "Origin: http://www.example.org\r\n"
16501 "Sec-WebSocket-Version: 13\r\n"
16502 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416503 };
16504
16505 // The proxy responds to the connect with a 407, using a persistent
16506 // connection.
16507 MockRead data_reads[] = {
16508 // No credentials.
16509 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
16510 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5416511 MockRead("Content-Length: 0\r\n"),
16512 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416513
16514 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16515
16516 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16517 MockRead("Upgrade: websocket\r\n"),
16518 MockRead("Connection: Upgrade\r\n"),
16519 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16520 };
16521
16522 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16523 arraysize(data_writes));
16524 session_deps_.socket_factory->AddSocketDataProvider(&data);
16525 SSLSocketDataProvider ssl(ASYNC, OK);
16526 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16527
bnc87dcefc2017-05-25 12:47:5816528 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916529 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416530 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16531 trans->SetWebSocketHandshakeStreamCreateHelper(
16532 &websocket_stream_create_helper);
16533
16534 {
16535 TestCompletionCallback callback;
16536
tfarina42834112016-09-22 13:38:2016537 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416539
16540 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116541 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416542 }
16543
16544 const HttpResponseInfo* response = trans->GetResponseInfo();
16545 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216546 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416547 EXPECT_EQ(407, response->headers->response_code());
16548
16549 {
16550 TestCompletionCallback callback;
16551
16552 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16553 callback.callback());
robpercival214763f2016-07-01 23:27:0116554 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416555
16556 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116557 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416558 }
16559
16560 response = trans->GetResponseInfo();
16561 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216562 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416563
16564 EXPECT_EQ(101, response->headers->response_code());
16565
16566 trans.reset();
16567 session->CloseAllConnections();
16568}
16569
16570// Verify that proxy headers are not sent to the destination server when
16571// establishing a tunnel for an insecure WebSocket connection.
16572// This requires the authentication info to be injected into the auth cache
16573// due to crbug.com/395064
16574// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116575TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416576 HttpRequestInfo request;
16577 request.method = "GET";
bncce36dca22015-04-21 22:11:2316578 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2416579 AddWebSocketHeaders(&request.extra_headers);
16580
16581 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0316582 session_deps_.proxy_service =
16583 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2416584
danakj1fd259a02016-04-16 03:17:0916585 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416586
16587 MockWrite data_writes[] = {
16588 // Try to establish a tunnel for the WebSocket connection, with
16589 // credentials. Because WebSockets have a separate set of socket pools,
16590 // they cannot and will not use the same TCP/IP connection as the
16591 // preflight HTTP request.
16592 MockWrite(
bncce36dca22015-04-21 22:11:2316593 "CONNECT www.example.org:80 HTTP/1.1\r\n"
16594 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2416595 "Proxy-Connection: keep-alive\r\n"
16596 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
16597
16598 MockWrite(
16599 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2316600 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416601 "Connection: Upgrade\r\n"
16602 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2316603 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2416604 "Sec-WebSocket-Version: 13\r\n"
16605 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
16606 };
16607
16608 MockRead data_reads[] = {
16609 // HTTP CONNECT with credentials.
16610 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16611
16612 // WebSocket connection established inside tunnel.
16613 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
16614 MockRead("Upgrade: websocket\r\n"),
16615 MockRead("Connection: Upgrade\r\n"),
16616 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
16617 };
16618
16619 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16620 arraysize(data_writes));
16621 session_deps_.socket_factory->AddSocketDataProvider(&data);
16622
16623 session->http_auth_cache()->Add(
16624 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
16625 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
16626
bnc87dcefc2017-05-25 12:47:5816627 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916628 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416629 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
16630 trans->SetWebSocketHandshakeStreamCreateHelper(
16631 &websocket_stream_create_helper);
16632
16633 TestCompletionCallback callback;
16634
tfarina42834112016-09-22 13:38:2016635 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416637
16638 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116639 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416640
16641 const HttpResponseInfo* response = trans->GetResponseInfo();
16642 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216643 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416644
16645 EXPECT_EQ(101, response->headers->response_code());
16646
16647 trans.reset();
16648 session->CloseAllConnections();
16649}
16650
bncd16676a2016-07-20 16:23:0116651TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0916652 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216653 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916654 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216655 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216656
16657 HttpRequestInfo request;
16658 request.method = "POST";
16659 request.url = GURL("http://www.foo.com/");
16660 request.upload_data_stream = &upload_data_stream;
16661
danakj1fd259a02016-04-16 03:17:0916662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616663 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216664 MockWrite data_writes[] = {
16665 MockWrite("POST / HTTP/1.1\r\n"
16666 "Host: www.foo.com\r\n"
16667 "Connection: keep-alive\r\n"
16668 "Content-Length: 3\r\n\r\n"),
16669 MockWrite("foo"),
16670 };
16671
16672 MockRead data_reads[] = {
16673 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16674 MockRead(SYNCHRONOUS, OK),
16675 };
16676 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16677 arraysize(data_writes));
16678 session_deps_.socket_factory->AddSocketDataProvider(&data);
16679
16680 TestCompletionCallback callback;
16681
16682 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016683 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116684 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216685
16686 std::string response_data;
bnc691fda62016-08-12 00:43:1616687 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216688
16689 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616690 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216691 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616692 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216693}
16694
bncd16676a2016-07-20 16:23:0116695TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0916696 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216697 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916698 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216699 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2216700
16701 HttpRequestInfo request;
16702 request.method = "POST";
16703 request.url = GURL("http://www.foo.com/");
16704 request.upload_data_stream = &upload_data_stream;
16705
danakj1fd259a02016-04-16 03:17:0916706 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616707 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216708 MockWrite data_writes[] = {
16709 MockWrite("POST / HTTP/1.1\r\n"
16710 "Host: www.foo.com\r\n"
16711 "Connection: keep-alive\r\n"
16712 "Content-Length: 3\r\n\r\n"),
16713 MockWrite("foo"),
16714 };
16715
16716 MockRead data_reads[] = {
16717 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16718 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16719 MockRead(SYNCHRONOUS, OK),
16720 };
16721 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16722 arraysize(data_writes));
16723 session_deps_.socket_factory->AddSocketDataProvider(&data);
16724
16725 TestCompletionCallback callback;
16726
16727 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016728 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116729 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216730
16731 std::string response_data;
bnc691fda62016-08-12 00:43:1616732 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216733
16734 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616735 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216736 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616737 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216738}
16739
bncd16676a2016-07-20 16:23:0116740TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216741 ChunkedUploadDataStream upload_data_stream(0);
16742
16743 HttpRequestInfo request;
16744 request.method = "POST";
16745 request.url = GURL("http://www.foo.com/");
16746 request.upload_data_stream = &upload_data_stream;
16747
danakj1fd259a02016-04-16 03:17:0916748 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616749 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2216750 // Send headers successfully, but get an error while sending the body.
16751 MockWrite data_writes[] = {
16752 MockWrite("POST / HTTP/1.1\r\n"
16753 "Host: www.foo.com\r\n"
16754 "Connection: keep-alive\r\n"
16755 "Transfer-Encoding: chunked\r\n\r\n"),
16756 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16757 };
16758
16759 MockRead data_reads[] = {
16760 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16761 MockRead(SYNCHRONOUS, OK),
16762 };
16763 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16764 arraysize(data_writes));
16765 session_deps_.socket_factory->AddSocketDataProvider(&data);
16766
16767 TestCompletionCallback callback;
16768
16769 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016770 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2216771
16772 base::RunLoop().RunUntilIdle();
16773 upload_data_stream.AppendData("f", 1, false);
16774
16775 base::RunLoop().RunUntilIdle();
16776 upload_data_stream.AppendData("oo", 2, true);
16777
robpercival214763f2016-07-01 23:27:0116778 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2216779
16780 std::string response_data;
bnc691fda62016-08-12 00:43:1616781 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2216782
16783 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
bnc691fda62016-08-12 00:43:1616784 trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:2216785 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
bnc691fda62016-08-12 00:43:1616786 trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2216787}
16788
rdsmith1d343be52016-10-21 20:37:5016789// Confirm that transactions whose throttle is created in (and stays in)
16790// the unthrottled state are not blocked.
16791TEST_F(HttpNetworkTransactionTest, ThrottlingUnthrottled) {
16792 TestNetworkStreamThrottler* throttler(nullptr);
16793 std::unique_ptr<HttpNetworkSession> session(
16794 CreateSessionWithThrottler(&session_deps_, &throttler));
16795
16796 // Send a simple request and make sure it goes through.
16797 HttpRequestInfo request;
16798 request.method = "GET";
16799 request.url = GURL("http://www.example.org/");
16800
bnc87dcefc2017-05-25 12:47:5816801 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916802 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016803
16804 MockWrite data_writes[] = {
16805 MockWrite("GET / HTTP/1.1\r\n"
16806 "Host: www.example.org\r\n"
16807 "Connection: keep-alive\r\n\r\n"),
16808 };
16809 MockRead data_reads[] = {
16810 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16811 MockRead(SYNCHRONOUS, OK),
16812 };
16813 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16814 arraysize(data_writes));
16815 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16816
16817 TestCompletionCallback callback;
16818 trans->Start(&request, callback.callback(), NetLogWithSource());
16819 EXPECT_EQ(OK, callback.WaitForResult());
16820}
16821
16822// Confirm requests can be blocked by a throttler, and are resumed
16823// when the throttle is unblocked.
16824TEST_F(HttpNetworkTransactionTest, ThrottlingBasic) {
16825 TestNetworkStreamThrottler* throttler(nullptr);
16826 std::unique_ptr<HttpNetworkSession> session(
16827 CreateSessionWithThrottler(&session_deps_, &throttler));
16828
16829 // Send a simple request and make sure it goes through.
16830 HttpRequestInfo request;
16831 request.method = "GET";
16832 request.url = GURL("http://www.example.org/");
16833
16834 MockWrite data_writes[] = {
16835 MockWrite("GET / HTTP/1.1\r\n"
16836 "Host: www.example.org\r\n"
16837 "Connection: keep-alive\r\n\r\n"),
16838 };
16839 MockRead data_reads[] = {
16840 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16841 MockRead(SYNCHRONOUS, OK),
16842 };
16843 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16844 arraysize(data_writes));
16845 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16846
16847 // Start a request that will be throttled at start; confirm it
16848 // doesn't complete.
16849 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816850 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916851 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016852
16853 TestCompletionCallback callback;
16854 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16855 EXPECT_EQ(ERR_IO_PENDING, rv);
16856
16857 base::RunLoop().RunUntilIdle();
16858 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16859 EXPECT_FALSE(callback.have_result());
16860
16861 // Confirm the request goes on to complete when unthrottled.
16862 throttler->UnthrottleAllRequests();
16863 base::RunLoop().RunUntilIdle();
16864 ASSERT_TRUE(callback.have_result());
16865 EXPECT_EQ(OK, callback.WaitForResult());
16866}
16867
16868// Destroy a request while it's throttled.
16869TEST_F(HttpNetworkTransactionTest, ThrottlingDestruction) {
16870 TestNetworkStreamThrottler* throttler(nullptr);
16871 std::unique_ptr<HttpNetworkSession> session(
16872 CreateSessionWithThrottler(&session_deps_, &throttler));
16873
16874 // Send a simple request and make sure it goes through.
16875 HttpRequestInfo request;
16876 request.method = "GET";
16877 request.url = GURL("http://www.example.org/");
16878
16879 MockWrite data_writes[] = {
16880 MockWrite("GET / HTTP/1.1\r\n"
16881 "Host: www.example.org\r\n"
16882 "Connection: keep-alive\r\n\r\n"),
16883 };
16884 MockRead data_reads[] = {
16885 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16886 MockRead(SYNCHRONOUS, OK),
16887 };
16888 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16889 arraysize(data_writes));
16890 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16891
16892 // Start a request that will be throttled at start; confirm it
16893 // doesn't complete.
16894 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816895 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916896 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016897
16898 TestCompletionCallback callback;
16899 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16900 EXPECT_EQ(ERR_IO_PENDING, rv);
16901
16902 base::RunLoop().RunUntilIdle();
16903 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16904 EXPECT_FALSE(callback.have_result());
16905
16906 EXPECT_EQ(1u, throttler->num_outstanding_requests());
16907 trans.reset();
16908 EXPECT_EQ(0u, throttler->num_outstanding_requests());
16909}
16910
16911// Confirm the throttler receives SetPriority calls.
16912TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySet) {
16913 TestNetworkStreamThrottler* throttler(nullptr);
16914 std::unique_ptr<HttpNetworkSession> session(
16915 CreateSessionWithThrottler(&session_deps_, &throttler));
16916
16917 // Send a simple request and make sure it goes through.
16918 HttpRequestInfo request;
16919 request.method = "GET";
16920 request.url = GURL("http://www.example.org/");
16921
16922 MockWrite data_writes[] = {
16923 MockWrite("GET / HTTP/1.1\r\n"
16924 "Host: www.example.org\r\n"
16925 "Connection: keep-alive\r\n\r\n"),
16926 };
16927 MockRead data_reads[] = {
16928 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16929 MockRead(SYNCHRONOUS, OK),
16930 };
16931 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16932 arraysize(data_writes));
16933 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16934
16935 throttler->set_throttle_new_requests(true);
Jeremy Roman0579ed62017-08-29 15:56:1916936 auto trans = std::make_unique<HttpNetworkTransaction>(IDLE, session.get());
rdsmith1d343be52016-10-21 20:37:5016937 // Start the transaction to associate a throttle with it.
16938 TestCompletionCallback callback;
16939 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16940 EXPECT_EQ(ERR_IO_PENDING, rv);
16941
16942 EXPECT_EQ(0, throttler->num_set_priority_calls());
16943 trans->SetPriority(LOW);
16944 EXPECT_EQ(1, throttler->num_set_priority_calls());
16945 EXPECT_EQ(LOW, throttler->last_priority_set());
16946
16947 throttler->UnthrottleAllRequests();
16948 base::RunLoop().RunUntilIdle();
16949 ASSERT_TRUE(callback.have_result());
16950 EXPECT_EQ(OK, callback.WaitForResult());
16951}
16952
16953// Confirm that unthrottling from a SetPriority call by the
16954// throttler works properly.
16955TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetUnthrottle) {
16956 TestNetworkStreamThrottler* throttler(nullptr);
16957 std::unique_ptr<HttpNetworkSession> session(
16958 CreateSessionWithThrottler(&session_deps_, &throttler));
16959
16960 // Send a simple request and make sure it goes through.
16961 HttpRequestInfo request;
16962 request.method = "GET";
16963 request.url = GURL("http://www.example.org/");
16964
16965 MockWrite data_writes[] = {
16966 MockWrite("GET / HTTP/1.1\r\n"
16967 "Host: www.example.org\r\n"
16968 "Connection: keep-alive\r\n\r\n"),
16969 };
16970 MockRead data_reads[] = {
16971 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
16972 MockRead(SYNCHRONOUS, OK),
16973 };
16974 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
16975 arraysize(data_writes));
16976 session_deps_.socket_factory->AddSocketDataProvider(&reads);
16977
16978 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
16979 data_writes, arraysize(data_writes));
16980 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
16981
16982 // Start a request that will be throttled at start; confirm it
16983 // doesn't complete.
16984 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5816985 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916986 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5016987
16988 TestCompletionCallback callback;
16989 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
16990 EXPECT_EQ(ERR_IO_PENDING, rv);
16991
16992 base::RunLoop().RunUntilIdle();
16993 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
16994 EXPECT_FALSE(callback.have_result());
16995
16996 // Create a new request, call SetPriority on it to unthrottle,
16997 // and make sure that allows the original request to complete.
Jeremy Roman0579ed62017-08-29 15:56:1916998 auto trans1 = std::make_unique<HttpNetworkTransaction>(LOW, session.get());
rdsmith1d343be52016-10-21 20:37:5016999 throttler->set_priority_change_closure(
17000 base::Bind(&TestNetworkStreamThrottler::UnthrottleAllRequests,
17001 base::Unretained(throttler)));
17002
17003 // Start the transaction to associate a throttle with it.
17004 TestCompletionCallback callback1;
17005 rv = trans1->Start(&request, callback1.callback(), NetLogWithSource());
17006 EXPECT_EQ(ERR_IO_PENDING, rv);
17007
17008 trans1->SetPriority(IDLE);
17009
17010 base::RunLoop().RunUntilIdle();
17011 ASSERT_TRUE(callback.have_result());
17012 EXPECT_EQ(OK, callback.WaitForResult());
17013 ASSERT_TRUE(callback1.have_result());
17014 EXPECT_EQ(OK, callback1.WaitForResult());
17015}
17016
17017// Transaction will be destroyed when the unique_ptr goes out of scope.
bnc87dcefc2017-05-25 12:47:5817018void DestroyTransaction(std::unique_ptr<HttpNetworkTransaction> transaction) {}
rdsmith1d343be52016-10-21 20:37:5017019
17020// Confirm that destroying a transaction from a SetPriority call by the
17021// throttler works properly.
17022TEST_F(HttpNetworkTransactionTest, ThrottlingPrioritySetDestroy) {
17023 TestNetworkStreamThrottler* throttler(nullptr);
17024 std::unique_ptr<HttpNetworkSession> session(
17025 CreateSessionWithThrottler(&session_deps_, &throttler));
17026
17027 // Send a simple request and make sure it goes through.
17028 HttpRequestInfo request;
17029 request.method = "GET";
17030 request.url = GURL("http://www.example.org/");
17031
17032 MockWrite data_writes[] = {
17033 MockWrite("GET / HTTP/1.1\r\n"
17034 "Host: www.example.org\r\n"
17035 "Connection: keep-alive\r\n\r\n"),
17036 };
17037 MockRead data_reads[] = {
17038 MockRead("HTTP/1.0 200 OK\r\n\r\n"), MockRead("hello world"),
17039 MockRead(SYNCHRONOUS, OK),
17040 };
17041 StaticSocketDataProvider reads(data_reads, arraysize(data_reads), data_writes,
17042 arraysize(data_writes));
17043 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17044
17045 StaticSocketDataProvider reads1(data_reads, arraysize(data_reads),
17046 data_writes, arraysize(data_writes));
17047 session_deps_.socket_factory->AddSocketDataProvider(&reads1);
17048
17049 // Start a request that will be throttled at start; confirm it
17050 // doesn't complete.
17051 throttler->set_throttle_new_requests(true);
bnc87dcefc2017-05-25 12:47:5817052 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917053 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
rdsmith1d343be52016-10-21 20:37:5017054
17055 TestCompletionCallback callback;
17056 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
17057 EXPECT_EQ(ERR_IO_PENDING, rv);
17058
17059 base::RunLoop().RunUntilIdle();
17060 EXPECT_EQ(LOAD_STATE_THROTTLED, trans->GetLoadState());
17061 EXPECT_FALSE(callback.have_result());
17062
17063 // Arrange for the set priority call on the above transaction to delete
17064 // the transaction.
bnc87dcefc2017-05-25 12:47:5817065 HttpNetworkTransaction* trans_ptr(trans.get());
rdsmith1d343be52016-10-21 20:37:5017066 throttler->set_priority_change_closure(
17067 base::Bind(&DestroyTransaction, base::Passed(&trans)));
17068
17069 // Call it and check results (partially a "doesn't crash" test).
17070 trans_ptr->SetPriority(IDLE);
17071 trans_ptr = nullptr; // No longer a valid pointer.
17072
17073 base::RunLoop().RunUntilIdle();
17074 ASSERT_FALSE(callback.have_result());
17075}
17076
nharperb7441ef2016-01-25 23:54:1417077#if !defined(OS_IOS)
bncd16676a2016-07-20 16:23:0117078TEST_F(HttpNetworkTransactionTest, TokenBindingSpdy) {
nharperb7441ef2016-01-25 23:54:1417079 const std::string https_url = "https://www.example.com";
17080 HttpRequestInfo request;
17081 request.url = GURL(https_url);
17082 request.method = "GET";
17083
17084 SSLSocketDataProvider ssl(ASYNC, OK);
17085 ssl.token_binding_negotiated = true;
17086 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
bnc3cf2a592016-08-11 14:48:3617087 ssl.next_proto = kProtoHTTP2;
nharperb7441ef2016-01-25 23:54:1417088 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17089
bnc42331402016-07-25 13:36:1517090 SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
bncdf80d44fd2016-07-15 20:27:4117091 SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
17092 MockRead reads[] = {CreateMockRead(resp), CreateMockRead(body),
nharperb7441ef2016-01-25 23:54:1417093 MockRead(ASYNC, ERR_IO_PENDING)};
17094 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
17095 session_deps_.socket_factory->AddSocketDataProvider(&data);
bnc87dcefc2017-05-25 12:47:5817096 session_deps_.channel_id_service =
Jeremy Roman0579ed62017-08-29 15:56:1917097 std::make_unique<ChannelIDService>(new DefaultChannelIDStore(nullptr));
danakj1fd259a02016-04-16 03:17:0917098 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1417099
17100 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17101 TestCompletionCallback callback;
17102 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017103 trans.Start(&request, callback.callback(), NetLogWithSource()));
fdorayf33fede2017-05-11 21:18:1017104
17105 NetTestSuite::GetScopedTaskEnvironment()->RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1417106
17107 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
17108 HttpRequestHeaders headers;
17109 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
17110 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
17111}
17112#endif // !defined(OS_IOS)
17113
eustasc7d27da2017-04-06 10:33:2017114void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17115 const std::string& accept_encoding,
17116 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317117 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017118 bool should_match) {
17119 HttpRequestInfo request;
17120 request.method = "GET";
17121 request.url = GURL("http://www.foo.com/");
17122 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17123 accept_encoding);
17124
17125 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17126 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17127 // Send headers successfully, but get an error while sending the body.
17128 MockWrite data_writes[] = {
17129 MockWrite("GET / HTTP/1.1\r\n"
17130 "Host: www.foo.com\r\n"
17131 "Connection: keep-alive\r\n"
17132 "Accept-Encoding: "),
17133 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17134 };
17135
sky50576f32017-05-01 19:28:0317136 std::string response_code = "200 OK";
17137 std::string extra;
17138 if (!location.empty()) {
17139 response_code = "301 Redirect\r\nLocation: ";
17140 response_code.append(location);
17141 }
17142
eustasc7d27da2017-04-06 10:33:2017143 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317144 MockRead("HTTP/1.0 "),
17145 MockRead(response_code.data()),
17146 MockRead("\r\nContent-Encoding: "),
17147 MockRead(content_encoding.data()),
17148 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017149 MockRead(SYNCHRONOUS, OK),
17150 };
17151 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
17152 arraysize(data_writes));
17153 session_deps->socket_factory->AddSocketDataProvider(&data);
17154
17155 TestCompletionCallback callback;
17156
17157 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17158 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17159
17160 rv = callback.WaitForResult();
17161 if (should_match) {
17162 EXPECT_THAT(rv, IsOk());
17163 } else {
17164 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17165 }
17166}
17167
17168TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317169 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017170}
17171
17172TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317173 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17174 true);
eustasc7d27da2017-04-06 10:33:2017175}
17176
17177TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17178 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317179 "", false);
17180}
17181
17182TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17183 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17184 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017185}
17186
xunjieli96f2a402017-06-05 17:24:2717187TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17188 ProxyConfig proxy_config;
17189 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17190 proxy_config.set_pac_mandatory(true);
17191 MockAsyncProxyResolver resolver;
17192 session_deps_.proxy_service.reset(new ProxyService(
Jeremy Roman0579ed62017-08-29 15:56:1917193 std::make_unique<ProxyConfigServiceFixed>(proxy_config),
xunjieli96f2a402017-06-05 17:24:2717194 base::WrapUnique(new FailingProxyResolverFactory), nullptr));
17195
17196 HttpRequestInfo request;
17197 request.method = "GET";
17198 request.url = GURL("http://www.example.org/");
17199
17200 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17201 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17202
17203 TestCompletionCallback callback;
17204
17205 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17206 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17207 EXPECT_THAT(callback.WaitForResult(),
17208 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17209}
17210
17211TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17212 ProxyConfig proxy_config;
17213 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17214 proxy_config.set_pac_mandatory(true);
17215 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17216 new MockAsyncProxyResolverFactory(false);
17217 MockAsyncProxyResolver resolver;
17218 session_deps_.proxy_service.reset(
Jeremy Roman0579ed62017-08-29 15:56:1917219 new ProxyService(std::make_unique<ProxyConfigServiceFixed>(proxy_config),
xunjieli96f2a402017-06-05 17:24:2717220 base::WrapUnique(proxy_resolver_factory), nullptr));
17221 HttpRequestInfo request;
17222 request.method = "GET";
17223 request.url = GURL("http://www.example.org/");
17224
17225 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17227
17228 TestCompletionCallback callback;
17229 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17230 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17231
17232 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17233 ERR_FAILED, &resolver);
17234 EXPECT_THAT(callback.WaitForResult(),
17235 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17236}
17237
17238TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
17239 session_deps_.proxy_service =
17240 ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443");
17241 session_deps_.enable_quic = false;
17242 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17243
17244 HttpRequestInfo request;
17245 request.method = "GET";
17246 request.url = GURL("http://www.example.org/");
17247
17248 TestCompletionCallback callback;
17249 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17250 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17251 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17252
17253 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17254}
17255
[email protected]89ceba9a2009-03-21 03:46:0617256} // namespace net