blob: 6e5b38e3f0e75d6d80ab84cc7e41514cfcb3bf53 [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>
danakj1fd259a02016-04-16 03:17:0912#include <memory>
[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"
[email protected]f36a8132011-09-02 18:36:3328#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3529#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3530#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0731#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3332#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0733#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2534#include "net/base/load_timing_info.h"
35#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2436#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1537#include "net/base/proxy_delegate.h"
[email protected]ac790b42009-12-02 04:31:3138#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5239#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4040#include "net/base/test_data_directory.h"
tbansal28e68f82016-02-04 02:56:1541#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0642#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2143#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1144#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1645#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5346#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2447#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1248#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0049#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2950#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1951#include "net/http/http_auth_scheme.h"
Adam Rice425cf122015-01-19 06:18:2452#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5753#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5254#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5655#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2456#include "net/http/http_request_headers.h"
[email protected]17291a022011-10-10 07:32:5357#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5758#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3859#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2460#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1961#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0762#include "net/log/net_log.h"
vishal.b62985ca92015-04-17 08:45:5163#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4664#include "net/log/test_net_log_entry.h"
65#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1366#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5367#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0368#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1169#include "net/proxy/proxy_resolver.h"
tbansal28e68f82016-02-04 02:56:1570#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1171#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4472#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1573#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0374#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4775#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0276#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0777#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4478#include "net/socket/socket_test_util.h"
79#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5480#include "net/spdy/spdy_framer.h"
81#include "net/spdy/spdy_session.h"
82#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0283#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1484#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5785#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0386#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5787#include "net/ssl/ssl_config_service_defaults.h"
88#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5489#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1190#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4491#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:1892#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:5293#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1594#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2795#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5296
[email protected]ad65a3e2013-12-25 18:18:0197using base::ASCIIToUTF16;
98
initial.commit586acc5fe2008-07-26 22:42:5299//-----------------------------------------------------------------------------
100
ttuttle859dc7a2015-04-23 19:42:29101namespace net {
102
[email protected]13c8a092010-07-29 06:15:44103namespace {
104
rdsmithebb50aa2015-11-12 03:44:38105enum TestCase {
106 // Test using the SPDY/3.1 protocol.
107 kTestCaseSPDY31,
108
109 // Test using the HTTP/2 protocol, without specifying a stream
110 // dependency based on the RequestPriority.
111 kTestCaseHTTP2NoPriorityDependencies,
112
113 // Test using the HTTP/2 protocol, specifying a stream
114 // dependency based on the RequestPriority.
115 kTestCaseHTTP2PriorityDependencies
116};
117
[email protected]42cba2fb2013-03-29 19:58:57118const base::string16 kBar(ASCIIToUTF16("bar"));
119const base::string16 kBar2(ASCIIToUTF16("bar2"));
120const base::string16 kBar3(ASCIIToUTF16("bar3"));
121const base::string16 kBaz(ASCIIToUTF16("baz"));
122const base::string16 kFirst(ASCIIToUTF16("first"));
123const base::string16 kFoo(ASCIIToUTF16("foo"));
124const base::string16 kFoo2(ASCIIToUTF16("foo2"));
125const base::string16 kFoo3(ASCIIToUTF16("foo3"));
126const base::string16 kFou(ASCIIToUTF16("fou"));
127const base::string16 kSecond(ASCIIToUTF16("second"));
128const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
129const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44130
ttuttle859dc7a2015-04-23 19:42:29131int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
132 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
133 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02134}
135
ttuttle859dc7a2015-04-23 19:42:29136int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
137 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
138 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02139}
140
ttuttle859dc7a2015-04-23 19:42:29141bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
142 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
143 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52144}
145
[email protected]f3da152d2012-06-02 01:00:57146// Takes in a Value created from a NetLogHttpResponseParameter, and returns
147// a JSONified list of headers as a single string. Uses single quotes instead
148// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27149bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57150 if (!params)
151 return false;
[email protected]ea5ef4c2013-06-13 22:50:27152 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57153 if (!params->GetList("headers", &header_list))
154 return false;
155 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34156 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28157 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57158 return true;
159}
160
[email protected]029c83b62013-01-24 05:28:20161// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
162// used.
ttuttle859dc7a2015-04-23 19:42:29163void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20164 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29165 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25166
[email protected]029c83b62013-01-24 05:28:20167 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
168 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
169
ttuttle859dc7a2015-04-23 19:42:29170 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20171 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25172
173 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25174
[email protected]3b23a222013-05-15 21:33:25175 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25176 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
177 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25178 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25179}
180
[email protected]029c83b62013-01-24 05:28:20181// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
182// used.
ttuttle859dc7a2015-04-23 19:42:29183void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25184 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20185 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29186 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20187
188 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
189 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
190
ttuttle859dc7a2015-04-23 19:42:29191 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
192 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20193 EXPECT_LE(load_timing_info.connect_timing.connect_end,
194 load_timing_info.send_start);
195
196 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20197
[email protected]3b23a222013-05-15 21:33:25198 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20199 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
200 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25201 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20202}
203
204// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
205// used.
ttuttle859dc7a2015-04-23 19:42:29206void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20207 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29208 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20209
ttuttle859dc7a2015-04-23 19:42:29210 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20211
212 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
213 EXPECT_LE(load_timing_info.proxy_resolve_start,
214 load_timing_info.proxy_resolve_end);
215 EXPECT_LE(load_timing_info.proxy_resolve_end,
216 load_timing_info.send_start);
217 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20218
[email protected]3b23a222013-05-15 21:33:25219 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20220 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
221 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25222 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20223}
224
225// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
226// used.
ttuttle859dc7a2015-04-23 19:42:29227void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20228 int connect_timing_flags) {
229 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29230 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20231
232 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
233 EXPECT_LE(load_timing_info.proxy_resolve_start,
234 load_timing_info.proxy_resolve_end);
235 EXPECT_LE(load_timing_info.proxy_resolve_end,
236 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29237 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
238 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20239 EXPECT_LE(load_timing_info.connect_timing.connect_end,
240 load_timing_info.send_start);
241
242 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20243
[email protected]3b23a222013-05-15 21:33:25244 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20245 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
246 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25247 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25248}
249
ttuttle859dc7a2015-04-23 19:42:29250void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24251 headers->SetHeader("Connection", "Upgrade");
252 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23253 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24254 headers->SetHeader("Sec-WebSocket-Version", "13");
255 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
256}
257
danakj1fd259a02016-04-16 03:17:09258std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42259 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34260 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14261}
262
[email protected]448d4ca52012-03-04 04:12:23263} // namespace
264
[email protected]23e482282013-06-14 16:08:02265class HttpNetworkTransactionTest
266 : public PlatformTest,
rdsmithebb50aa2015-11-12 03:44:38267 public ::testing::WithParamInterface<TestCase> {
[email protected]483fa202013-05-14 01:07:03268 public:
[email protected]23e482282013-06-14 16:08:02269 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03270 // Important to restore the per-pool limit first, since the pool limit must
271 // always be greater than group limit, and the tests reduce both limits.
272 ClientSocketPoolManager::set_max_sockets_per_pool(
273 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
274 ClientSocketPoolManager::set_max_sockets_per_group(
275 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
276 }
277
[email protected]e3ceb682011-06-28 23:55:46278 protected:
[email protected]23e482282013-06-14 16:08:02279 HttpNetworkTransactionTest()
rdsmithebb50aa2015-11-12 03:44:38280 : spdy_util_(GetProtocol(), GetDependenciesFromPriority()),
281 session_deps_(GetProtocol()),
[email protected]483fa202013-05-14 01:07:03282 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
283 HttpNetworkSession::NORMAL_SOCKET_POOL)),
284 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
285 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
rdsmith2e54d1f2016-03-21 19:48:17286 session_deps_.enable_priority_dependencies = GetDependenciesFromPriority();
[email protected]483fa202013-05-14 01:07:03287 }
[email protected]bb88e1d32013-05-03 23:11:07288
[email protected]e3ceb682011-06-28 23:55:46289 struct SimpleGetHelperResult {
290 int rv;
291 std::string status_line;
292 std::string response_data;
sclittlefb249892015-09-10 21:33:22293 int64_t total_received_bytes;
294 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25295 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47296 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59297 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46298 };
299
dcheng67be2b1f2014-10-27 21:47:29300 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50301 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34302 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54303 }
304
dcheng67be2b1f2014-10-27 21:47:29305 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50306 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34307 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09308 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34309 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09310 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50311 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34312 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09313 }
314
rdsmithebb50aa2015-11-12 03:44:38315 NextProto GetProtocol() const {
316 return GetParam() == kTestCaseSPDY31 ? kProtoSPDY31 : kProtoHTTP2;
317 }
318
319 bool GetDependenciesFromPriority() const {
320 return GetParam() == kTestCaseHTTP2PriorityDependencies;
321 }
322
bnc33b8cef42014-11-19 17:30:38323 const char* GetAlternateProtocolFromParam() {
rdsmithebb50aa2015-11-12 03:44:38324 return AlternateProtocolToString(
325 AlternateProtocolFromNextProto(GetProtocol()));
bnc33b8cef42014-11-19 17:30:38326 }
327
bncc958faa2015-07-31 18:14:52328 std::string GetAlternativeServiceHttpHeader() {
329 return std::string("Alt-Svc: ") + GetAlternateProtocolFromParam() +
bnc8bef8da22016-05-30 01:28:25330 "=\"www.example.org:443\"\r\n";
bncc958faa2015-07-31 18:14:52331 }
332
[email protected]202965992011-12-07 23:04:51333 // Either |write_failure| specifies a write failure or |read_failure|
334 // specifies a read failure when using a reused socket. In either case, the
335 // failure should cause the network transaction to resend the request, and the
336 // other argument should be NULL.
337 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
338 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52339
[email protected]a34f61ee2014-03-18 20:59:49340 // Either |write_failure| specifies a write failure or |read_failure|
341 // specifies a read failure when using a reused socket. In either case, the
342 // failure should cause the network transaction to resend the request, and the
343 // other argument should be NULL.
344 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10345 const MockRead* read_failure,
346 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49347
[email protected]5a60c8b2011-10-19 20:14:29348 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
349 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15350 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52351
[email protected]ff007e162009-05-23 09:13:15352 HttpRequestInfo request;
353 request.method = "GET";
bncce36dca22015-04-21 22:11:23354 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15355 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52356
vishal.b62985ca92015-04-17 08:45:51357 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07358 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09359 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
360 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41361 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27362
[email protected]5a60c8b2011-10-19 20:14:29363 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07364 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29365 }
initial.commit586acc5fe2008-07-26 22:42:52366
[email protected]49639fa2011-12-20 23:22:41367 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52368
eroman24bc6a12015-05-06 19:55:48369 EXPECT_TRUE(log.bound().IsCapturing());
[email protected]49639fa2011-12-20 23:22:41370 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15371 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52372
[email protected]ff007e162009-05-23 09:13:15373 out.rv = callback.WaitForResult();
sclittlefb249892015-09-10 21:33:22374 out.total_received_bytes = trans->GetTotalReceivedBytes();
375 out.total_sent_bytes = trans->GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25376
377 // Even in the failure cases that use this function, connections are always
378 // successfully established before the error.
379 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
380 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
381
[email protected]ff007e162009-05-23 09:13:15382 if (out.rv != OK)
383 return out;
384
385 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50386 // Can't use ASSERT_* inside helper functions like this, so
387 // return an error.
wezca1070932016-05-26 20:30:52388 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50389 out.rv = ERR_UNEXPECTED;
390 return out;
391 }
[email protected]ff007e162009-05-23 09:13:15392 out.status_line = response->headers->GetStatusLine();
393
[email protected]80a09a82012-11-16 17:40:06394 EXPECT_EQ("127.0.0.1", response->socket_address.host());
395 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19396
ttuttled9dbc652015-09-29 20:00:59397 bool got_endpoint =
398 trans->GetRemoteEndpoint(&out.remote_endpoint_after_start);
399 EXPECT_EQ(got_endpoint,
400 out.remote_endpoint_after_start.address().size() > 0);
401
[email protected]ff007e162009-05-23 09:13:15402 rv = ReadTransaction(trans.get(), &out.response_data);
403 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40404
mmenke43758e62015-05-04 21:09:46405 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40406 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39407 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40408 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12409 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39410 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40411 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39412 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
413 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15414
[email protected]f3da152d2012-06-02 01:00:57415 std::string line;
416 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
417 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
418
[email protected]79e1fd62013-06-20 06:50:04419 HttpRequestHeaders request_headers;
420 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
421 std::string value;
422 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23423 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04424 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
425 EXPECT_EQ("keep-alive", value);
426
427 std::string response_headers;
428 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23429 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04430 response_headers);
[email protected]3deb9a52010-11-11 00:24:40431
sclittlefb249892015-09-10 21:33:22432 out.total_received_bytes = trans->GetTotalReceivedBytes();
433 // The total number of sent bytes should not have changed.
434 EXPECT_EQ(out.total_sent_bytes, trans->GetTotalSentBytes());
435
ttuttle1f2d7e92015-04-28 16:17:47436 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47437 return out;
[email protected]ff007e162009-05-23 09:13:15438 }
initial.commit586acc5fe2008-07-26 22:42:52439
[email protected]5a60c8b2011-10-19 20:14:29440 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
441 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22442 MockWrite data_writes[] = {
443 MockWrite("GET / HTTP/1.1\r\n"
444 "Host: www.example.org\r\n"
445 "Connection: keep-alive\r\n\r\n"),
446 };
[email protected]5a60c8b2011-10-19 20:14:29447
sclittlefb249892015-09-10 21:33:22448 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
449 arraysize(data_writes));
450 StaticSocketDataProvider* data[] = {&reads};
451 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
452
453 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
454 out.total_sent_bytes);
455 return out;
[email protected]b8015c42013-12-24 15:18:19456 }
457
[email protected]ff007e162009-05-23 09:13:15458 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
459 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52460
[email protected]ff007e162009-05-23 09:13:15461 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07462
463 void BypassHostCacheOnRefreshHelper(int load_flags);
464
465 void CheckErrorIsPassedBack(int error, IoMode mode);
466
[email protected]4bd46222013-05-14 19:32:23467 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07468 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03469
470 // Original socket limits. Some tests set these. Safest to always restore
471 // them once each test has been run.
472 int old_max_group_sockets_;
473 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15474};
[email protected]231d5a32008-09-13 00:45:27475
rdsmithebb50aa2015-11-12 03:44:38476INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc57685ae62015-03-10 21:27:20477 HttpNetworkTransactionTest,
rdsmithebb50aa2015-11-12 03:44:38478 testing::Values(kTestCaseSPDY31,
479 kTestCaseHTTP2NoPriorityDependencies,
480 kTestCaseHTTP2PriorityDependencies));
[email protected]23e482282013-06-14 16:08:02481
[email protected]448d4ca52012-03-04 04:12:23482namespace {
483
[email protected]1826a402014-01-08 15:40:48484class BeforeNetworkStartHandler {
485 public:
486 explicit BeforeNetworkStartHandler(bool defer)
487 : defer_on_before_network_start_(defer),
488 observed_before_network_start_(false) {}
489
490 void OnBeforeNetworkStart(bool* defer) {
491 *defer = defer_on_before_network_start_;
492 observed_before_network_start_ = true;
493 }
494
495 bool observed_before_network_start() const {
496 return observed_before_network_start_;
497 }
498
499 private:
500 const bool defer_on_before_network_start_;
501 bool observed_before_network_start_;
502
503 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
504};
505
[email protected]597a1ab2014-06-26 08:12:27506class BeforeProxyHeadersSentHandler {
507 public:
508 BeforeProxyHeadersSentHandler()
509 : observed_before_proxy_headers_sent_(false) {}
510
[email protected]1252d42f2014-07-01 21:20:20511 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
512 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27513 observed_before_proxy_headers_sent_ = true;
514 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
515 }
516
517 bool observed_before_proxy_headers_sent() const {
518 return observed_before_proxy_headers_sent_;
519 }
520
521 std::string observed_proxy_server_uri() const {
522 return observed_proxy_server_uri_;
523 }
524
525 private:
526 bool observed_before_proxy_headers_sent_;
527 std::string observed_proxy_server_uri_;
528
529 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
530};
531
[email protected]15a5ccf82008-10-23 19:57:43532// Fill |str| with a long header list that consumes >= |size| bytes.
533void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51534 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19535 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
536 const int sizeof_row = strlen(row);
537 const int num_rows = static_cast<int>(
538 ceil(static_cast<float>(size) / sizeof_row));
539 const int sizeof_data = num_rows * sizeof_row;
540 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43541 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51542
[email protected]4ddaf2502008-10-23 18:26:19543 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43544 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19545}
546
thakis84dff942015-07-28 20:47:38547#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29548// Alternative functions that eliminate randomness and dependency on the local
549// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14550void MockGenerateRandom1(uint8_t* output, size_t n) {
551 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
552 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29553 static size_t current_byte = 0;
554 for (size_t i = 0; i < n; ++i) {
555 output[i] = bytes[current_byte++];
556 current_byte %= arraysize(bytes);
557 }
558}
559
avibf0746c2015-12-09 19:53:14560void MockGenerateRandom2(uint8_t* output, size_t n) {
561 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
562 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
563 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29564 static size_t current_byte = 0;
565 for (size_t i = 0; i < n; ++i) {
566 output[i] = bytes[current_byte++];
567 current_byte %= arraysize(bytes);
568 }
569}
570
[email protected]fe2bc6a2009-03-23 16:52:20571std::string MockGetHostName() {
572 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29573}
thakis84dff942015-07-28 20:47:38574#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29575
[email protected]e60e47a2010-07-14 03:37:18576template<typename ParentPool>
577class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31578 public:
[email protected]9e1bdd32011-02-03 21:48:34579 CaptureGroupNameSocketPool(HostResolver* host_resolver,
580 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18581
[email protected]d80a4322009-08-14 07:07:49582 const std::string last_group_name_received() const {
583 return last_group_name_;
584 }
585
dmichaeld6e570d2014-12-18 22:30:57586 int RequestSocket(const std::string& group_name,
587 const void* socket_params,
588 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15589 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57590 ClientSocketHandle* handle,
591 const CompletionCallback& callback,
592 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31593 last_group_name_ = group_name;
594 return ERR_IO_PENDING;
595 }
dmichaeld6e570d2014-12-18 22:30:57596 void CancelRequest(const std::string& group_name,
597 ClientSocketHandle* handle) override {}
598 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09599 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57600 int id) override {}
601 void CloseIdleSockets() override {}
602 int IdleSocketCount() const override { return 0; }
603 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31604 return 0;
605 }
dmichaeld6e570d2014-12-18 22:30:57606 LoadState GetLoadState(const std::string& group_name,
607 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31608 return LOAD_STATE_IDLE;
609 }
dmichaeld6e570d2014-12-18 22:30:57610 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26611 return base::TimeDelta();
612 }
[email protected]d80a4322009-08-14 07:07:49613
614 private:
[email protected]04e5be32009-06-26 20:00:31615 std::string last_group_name_;
616};
617
[email protected]ab739042011-04-07 15:22:28618typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
619CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13620typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
621CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06622typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11623CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18624typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
625CaptureGroupNameSSLSocketPool;
626
rkaplowd90695c2015-03-25 22:12:41627template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18628CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34629 HostResolver* host_resolver,
630 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21631 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18632
hashimoto0d3e4fb2015-01-09 05:02:50633template <>
[email protected]2df19bb2010-08-25 20:13:46634CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21635 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34636 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41637 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50638}
[email protected]2df19bb2010-08-25 20:13:46639
[email protected]007b3f82013-04-09 08:46:45640template <>
[email protected]e60e47a2010-07-14 03:37:18641CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21642 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34643 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45644 : SSLClientSocketPool(0,
645 0,
[email protected]007b3f82013-04-09 08:46:45646 cert_verifier,
647 NULL,
648 NULL,
[email protected]284303b62013-11-28 15:11:54649 NULL,
eranm6571b2b2014-12-03 15:53:23650 NULL,
[email protected]007b3f82013-04-09 08:46:45651 std::string(),
652 NULL,
653 NULL,
654 NULL,
655 NULL,
656 NULL,
[email protected]8e458552014-08-05 00:02:15657 NULL) {
658}
[email protected]2227c692010-05-04 15:36:11659
[email protected]231d5a32008-09-13 00:45:27660//-----------------------------------------------------------------------------
661
[email protected]79cb5c12011-09-12 13:12:04662// Helper functions for validating that AuthChallengeInfo's are correctly
663// configured for common cases.
664bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
665 if (!auth_challenge)
666 return false;
667 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23668 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04669 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19670 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04671 return true;
672}
673
674bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
675 if (!auth_challenge)
676 return false;
677 EXPECT_TRUE(auth_challenge->is_proxy);
678 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
679 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19680 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04681 return true;
682}
683
684bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
685 if (!auth_challenge)
686 return false;
687 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23688 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04689 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19690 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04691 return true;
692}
693
thakis84dff942015-07-28 20:47:38694#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04695bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
696 if (!auth_challenge)
697 return false;
698 EXPECT_FALSE(auth_challenge->is_proxy);
699 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
700 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19701 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04702 return true;
703}
thakis84dff942015-07-28 20:47:38704#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04705
[email protected]448d4ca52012-03-04 04:12:23706} // namespace
707
[email protected]23e482282013-06-14 16:08:02708TEST_P(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09709 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
710 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41711 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27712}
713
[email protected]23e482282013-06-14 16:08:02714TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27715 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35716 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
717 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06718 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27719 };
[email protected]31a2bfe2010-02-09 08:03:39720 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
721 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42722 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27723 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
724 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22725 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
726 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47727 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59728
729 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27730}
731
732// Response with no status line.
[email protected]23e482282013-06-14 16:08:02733TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27734 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35735 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06736 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27737 };
[email protected]31a2bfe2010-02-09 08:03:39738 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
739 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42740 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27741 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
742 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22743 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
744 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27745}
746
747// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02748TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27749 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35750 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06751 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27752 };
[email protected]31a2bfe2010-02-09 08:03:39753 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
754 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42755 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27756 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
757 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22758 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
759 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27760}
761
762// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02763TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27764 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35765 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06766 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27767 };
[email protected]31a2bfe2010-02-09 08:03:39768 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
769 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42770 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27771 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
772 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22773 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
774 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27775}
776
777// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02778TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27779 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35780 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06781 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27782 };
[email protected]31a2bfe2010-02-09 08:03:39783 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
784 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42785 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25786 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
787 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
sclittlefb249892015-09-10 21:33:22788 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
789 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27790}
791
792// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02793TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27794 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35795 MockRead("\n"),
796 MockRead("\n"),
797 MockRead("Q"),
798 MockRead("J"),
799 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06800 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27801 };
[email protected]31a2bfe2010-02-09 08:03:39802 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
803 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42804 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27805 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
806 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22807 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
808 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27809}
810
811// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02812TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27813 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35814 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06815 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27816 };
[email protected]31a2bfe2010-02-09 08:03:39817 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
818 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42819 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27820 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
821 EXPECT_EQ("HTT", out.response_data);
sclittlefb249892015-09-10 21:33:22822 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
823 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52824}
825
[email protected]f9d44aa2008-09-23 23:57:17826// Simulate a 204 response, lacking a Content-Length header, sent over a
827// persistent connection. The response should still terminate since a 204
828// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02829TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19830 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17831 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35832 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19833 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06834 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17835 };
[email protected]31a2bfe2010-02-09 08:03:39836 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
837 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42838 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17839 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
840 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22841 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
842 int64_t response_size = reads_size - strlen(junk);
843 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17844}
845
[email protected]0877e3d2009-10-17 22:29:57846// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02847TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19848 std::string final_chunk = "0\r\n\r\n";
849 std::string extra_data = "HTTP/1.1 200 OK\r\n";
850 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57851 MockRead data_reads[] = {
852 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
853 MockRead("5\r\nHello\r\n"),
854 MockRead("1\r\n"),
855 MockRead(" \r\n"),
856 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19857 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06858 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57859 };
[email protected]31a2bfe2010-02-09 08:03:39860 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
861 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57862 EXPECT_EQ(OK, out.rv);
863 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
864 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22865 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
866 int64_t response_size = reads_size - extra_data.size();
867 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57868}
869
[email protected]9fe44f52010-09-23 18:36:00870// Next tests deal with http://crbug.com/56344.
871
[email protected]23e482282013-06-14 16:08:02872TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00873 MultipleContentLengthHeadersNoTransferEncoding) {
874 MockRead data_reads[] = {
875 MockRead("HTTP/1.1 200 OK\r\n"),
876 MockRead("Content-Length: 10\r\n"),
877 MockRead("Content-Length: 5\r\n\r\n"),
878 };
879 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
880 arraysize(data_reads));
881 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
882}
883
[email protected]23e482282013-06-14 16:08:02884TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04885 DuplicateContentLengthHeadersNoTransferEncoding) {
886 MockRead data_reads[] = {
887 MockRead("HTTP/1.1 200 OK\r\n"),
888 MockRead("Content-Length: 5\r\n"),
889 MockRead("Content-Length: 5\r\n\r\n"),
890 MockRead("Hello"),
891 };
892 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
893 arraysize(data_reads));
894 EXPECT_EQ(OK, out.rv);
895 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
896 EXPECT_EQ("Hello", out.response_data);
897}
898
[email protected]23e482282013-06-14 16:08:02899TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04900 ComplexContentLengthHeadersNoTransferEncoding) {
901 // More than 2 dupes.
902 {
903 MockRead data_reads[] = {
904 MockRead("HTTP/1.1 200 OK\r\n"),
905 MockRead("Content-Length: 5\r\n"),
906 MockRead("Content-Length: 5\r\n"),
907 MockRead("Content-Length: 5\r\n\r\n"),
908 MockRead("Hello"),
909 };
910 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
911 arraysize(data_reads));
912 EXPECT_EQ(OK, out.rv);
913 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
914 EXPECT_EQ("Hello", out.response_data);
915 }
916 // HTTP/1.0
917 {
918 MockRead data_reads[] = {
919 MockRead("HTTP/1.0 200 OK\r\n"),
920 MockRead("Content-Length: 5\r\n"),
921 MockRead("Content-Length: 5\r\n"),
922 MockRead("Content-Length: 5\r\n\r\n"),
923 MockRead("Hello"),
924 };
925 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
926 arraysize(data_reads));
927 EXPECT_EQ(OK, out.rv);
928 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
929 EXPECT_EQ("Hello", out.response_data);
930 }
931 // 2 dupes and one mismatched.
932 {
933 MockRead data_reads[] = {
934 MockRead("HTTP/1.1 200 OK\r\n"),
935 MockRead("Content-Length: 10\r\n"),
936 MockRead("Content-Length: 10\r\n"),
937 MockRead("Content-Length: 5\r\n\r\n"),
938 };
939 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
940 arraysize(data_reads));
941 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
942 }
943}
944
[email protected]23e482282013-06-14 16:08:02945TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00946 MultipleContentLengthHeadersTransferEncoding) {
947 MockRead data_reads[] = {
948 MockRead("HTTP/1.1 200 OK\r\n"),
949 MockRead("Content-Length: 666\r\n"),
950 MockRead("Content-Length: 1337\r\n"),
951 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
952 MockRead("5\r\nHello\r\n"),
953 MockRead("1\r\n"),
954 MockRead(" \r\n"),
955 MockRead("5\r\nworld\r\n"),
956 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06957 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00958 };
959 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
960 arraysize(data_reads));
961 EXPECT_EQ(OK, out.rv);
962 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
963 EXPECT_EQ("Hello world", out.response_data);
964}
965
[email protected]1628fe92011-10-04 23:04:55966// Next tests deal with http://crbug.com/98895.
967
968// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02969TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55970 MockRead data_reads[] = {
971 MockRead("HTTP/1.1 200 OK\r\n"),
972 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
973 MockRead("Content-Length: 5\r\n\r\n"),
974 MockRead("Hello"),
975 };
976 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
977 arraysize(data_reads));
978 EXPECT_EQ(OK, out.rv);
979 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
980 EXPECT_EQ("Hello", out.response_data);
981}
982
[email protected]54a9c6e52012-03-21 20:10:59983// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02984TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59985 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55986 MockRead data_reads[] = {
987 MockRead("HTTP/1.1 200 OK\r\n"),
988 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
989 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
990 MockRead("Content-Length: 5\r\n\r\n"),
991 MockRead("Hello"),
992 };
993 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
994 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59995 EXPECT_EQ(OK, out.rv);
996 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
997 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55998}
999
1000// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:021001TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551002 MockRead data_reads[] = {
1003 MockRead("HTTP/1.1 200 OK\r\n"),
1004 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1005 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1006 MockRead("Content-Length: 5\r\n\r\n"),
1007 MockRead("Hello"),
1008 };
1009 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1010 arraysize(data_reads));
1011 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
1012}
1013
[email protected]54a9c6e52012-03-21 20:10:591014// Checks that two identical Location headers result in no error.
1015// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:021016TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551017 MockRead data_reads[] = {
1018 MockRead("HTTP/1.1 302 Redirect\r\n"),
1019 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591020 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551021 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061022 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551023 };
1024
1025 HttpRequestInfo request;
1026 request.method = "GET";
1027 request.url = GURL("http://redirect.com/");
1028 request.load_flags = 0;
1029
danakj1fd259a02016-04-16 03:17:091030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1031 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411032 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:551033
1034 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071035 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551036
[email protected]49639fa2011-12-20 23:22:411037 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551038
[email protected]49639fa2011-12-20 23:22:411039 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:551040 EXPECT_EQ(ERR_IO_PENDING, rv);
1041
1042 EXPECT_EQ(OK, callback.WaitForResult());
1043
1044 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521045 ASSERT_TRUE(response);
1046 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551047 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1048 std::string url;
1049 EXPECT_TRUE(response->headers->IsRedirect(&url));
1050 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151051 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551052}
1053
[email protected]1628fe92011-10-04 23:04:551054// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021055TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551056 MockRead data_reads[] = {
1057 MockRead("HTTP/1.1 302 Redirect\r\n"),
1058 MockRead("Location: http://good.com/\r\n"),
1059 MockRead("Location: http://evil.com/\r\n"),
1060 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061061 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551062 };
1063 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1064 arraysize(data_reads));
1065 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1066}
1067
[email protected]ef0faf2e72009-03-05 23:27:231068// Do a request using the HEAD method. Verify that we don't try to read the
1069// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021070TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421071 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231072 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231073 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231074 request.load_flags = 0;
1075
danakj1fd259a02016-04-16 03:17:091076 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1077 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411078 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271079 BeforeProxyHeadersSentHandler proxy_headers_handler;
1080 trans->SetBeforeProxyHeadersSentCallback(
1081 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1082 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271083
[email protected]ef0faf2e72009-03-05 23:27:231084 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131085 MockWrite("HEAD / HTTP/1.1\r\n"
1086 "Host: www.example.org\r\n"
1087 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231088 };
1089 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231090 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1091 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231092
mmenked39192ee2015-12-09 00:57:231093 // No response body because the test stops reading here.
1094 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231095 };
1096
[email protected]31a2bfe2010-02-09 08:03:391097 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1098 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071099 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231100
[email protected]49639fa2011-12-20 23:22:411101 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231102
[email protected]49639fa2011-12-20 23:22:411103 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421104 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231105
1106 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421107 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231108
[email protected]1c773ea12009-04-28 19:58:421109 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521110 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231111
1112 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521113 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231114 EXPECT_EQ(1234, response->headers->GetContentLength());
1115 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151116 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271117 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231118
1119 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101120 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231121 bool has_server_header = response->headers->EnumerateHeader(
1122 &iter, "Server", &server_header);
1123 EXPECT_TRUE(has_server_header);
1124 EXPECT_EQ("Blah", server_header);
1125
1126 // Reading should give EOF right away, since there is no message body
1127 // (despite non-zero content-length).
1128 std::string response_data;
1129 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421130 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231131 EXPECT_EQ("", response_data);
1132}
1133
[email protected]23e482282013-06-14 16:08:021134TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521136
1137 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351138 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1139 MockRead("hello"),
1140 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1141 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061142 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521143 };
[email protected]31a2bfe2010-02-09 08:03:391144 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071145 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521146
[email protected]0b0bf032010-09-21 18:08:501147 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521148 "hello", "world"
1149 };
1150
1151 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421152 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521153 request.method = "GET";
bncce36dca22015-04-21 22:11:231154 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521155 request.load_flags = 0;
1156
danakj1fd259a02016-04-16 03:17:091157 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501158 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271159
[email protected]49639fa2011-12-20 23:22:411160 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521161
[email protected]49639fa2011-12-20 23:22:411162 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421163 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521164
1165 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421166 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521167
[email protected]1c773ea12009-04-28 19:58:421168 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521169 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521170
wezca1070932016-05-26 20:30:521171 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251172 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151173 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521174
1175 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571176 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421177 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251178 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521179 }
1180}
1181
[email protected]23e482282013-06-14 16:08:021182TEST_P(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091183 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221184 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:091185 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:221186 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271187
[email protected]1c773ea12009-04-28 19:58:421188 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521189 request.method = "POST";
1190 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271191 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521192 request.load_flags = 0;
1193
danakj1fd259a02016-04-16 03:17:091194 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1195 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411196 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271197
initial.commit586acc5fe2008-07-26 22:42:521198 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351199 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1200 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1201 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061202 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521203 };
[email protected]31a2bfe2010-02-09 08:03:391204 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071205 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521206
[email protected]49639fa2011-12-20 23:22:411207 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521208
[email protected]49639fa2011-12-20 23:22:411209 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421210 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521211
1212 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421213 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521214
[email protected]1c773ea12009-04-28 19:58:421215 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521216 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521217
wezca1070932016-05-26 20:30:521218 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251219 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521220
1221 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571222 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421223 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251224 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521225}
1226
[email protected]3a2d3662009-03-27 03:49:141227// This test is almost the same as Ignores100 above, but the response contains
1228// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571229// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021230TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421231 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141232 request.method = "GET";
1233 request.url = GURL("http://www.foo.com/");
1234 request.load_flags = 0;
1235
danakj1fd259a02016-04-16 03:17:091236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1237 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411238 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271239
[email protected]3a2d3662009-03-27 03:49:141240 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571241 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1242 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141243 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061244 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141245 };
[email protected]31a2bfe2010-02-09 08:03:391246 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071247 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141248
[email protected]49639fa2011-12-20 23:22:411249 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141250
[email protected]49639fa2011-12-20 23:22:411251 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421252 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141253
1254 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421255 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141256
[email protected]1c773ea12009-04-28 19:58:421257 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521258 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141259
wezca1070932016-05-26 20:30:521260 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141261 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1262
1263 std::string response_data;
1264 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421265 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141266 EXPECT_EQ("hello world", response_data);
1267}
1268
[email protected]23e482282013-06-14 16:08:021269TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081270 HttpRequestInfo request;
1271 request.method = "POST";
1272 request.url = GURL("http://www.foo.com/");
1273 request.load_flags = 0;
1274
danakj1fd259a02016-04-16 03:17:091275 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1276 std::unique_ptr<HttpTransaction> trans(
zmo9528c9f42015-08-04 22:12:081277 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1278
1279 MockRead data_reads[] = {
1280 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1281 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381282 };
zmo9528c9f42015-08-04 22:12:081283 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1284 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381285
zmo9528c9f42015-08-04 22:12:081286 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381287
zmo9528c9f42015-08-04 22:12:081288 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1289 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381290
zmo9528c9f42015-08-04 22:12:081291 rv = callback.WaitForResult();
1292 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381293
zmo9528c9f42015-08-04 22:12:081294 std::string response_data;
1295 rv = ReadTransaction(trans.get(), &response_data);
1296 EXPECT_EQ(OK, rv);
1297 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381298}
1299
[email protected]23e482282013-06-14 16:08:021300TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381301 HttpRequestInfo request;
1302 request.method = "POST";
1303 request.url = GURL("http://www.foo.com/");
1304 request.load_flags = 0;
1305
danakj1fd259a02016-04-16 03:17:091306 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1307 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411308 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271309
[email protected]ee9410e72010-01-07 01:42:381310 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061311 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381312 };
[email protected]31a2bfe2010-02-09 08:03:391313 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071314 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381315
[email protected]49639fa2011-12-20 23:22:411316 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381317
[email protected]49639fa2011-12-20 23:22:411318 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381319 EXPECT_EQ(ERR_IO_PENDING, rv);
1320
1321 rv = callback.WaitForResult();
1322 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1323}
1324
[email protected]23e482282013-06-14 16:08:021325void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511326 const MockWrite* write_failure,
1327 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421328 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521329 request.method = "GET";
1330 request.url = GURL("http://www.foo.com/");
1331 request.load_flags = 0;
1332
vishal.b62985ca92015-04-17 08:45:511333 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071334 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091335 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271336
[email protected]202965992011-12-07 23:04:511337 // Written data for successfully sending both requests.
1338 MockWrite data1_writes[] = {
1339 MockWrite("GET / HTTP/1.1\r\n"
1340 "Host: www.foo.com\r\n"
1341 "Connection: keep-alive\r\n\r\n"),
1342 MockWrite("GET / HTTP/1.1\r\n"
1343 "Host: www.foo.com\r\n"
1344 "Connection: keep-alive\r\n\r\n")
1345 };
1346
1347 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521348 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351349 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1350 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061351 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521352 };
[email protected]202965992011-12-07 23:04:511353
1354 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491355 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511356 data1_writes[1] = *write_failure;
1357 } else {
1358 ASSERT_TRUE(read_failure);
1359 data1_reads[2] = *read_failure;
1360 }
1361
1362 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1363 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071364 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521365
1366 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351367 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1368 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061369 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521370 };
[email protected]31a2bfe2010-02-09 08:03:391371 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071372 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521373
thestig9d3bb0c2015-01-24 00:49:511374 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521375 "hello", "world"
1376 };
1377
avibf0746c2015-12-09 19:53:141378 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521379 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411380 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521381
danakj1fd259a02016-04-16 03:17:091382 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501383 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521384
[email protected]49639fa2011-12-20 23:22:411385 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421386 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521387
1388 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421389 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521390
[email protected]58e32bb2013-01-21 18:23:251391 LoadTimingInfo load_timing_info;
1392 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1393 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1394 if (i == 0) {
1395 first_socket_log_id = load_timing_info.socket_log_id;
1396 } else {
1397 // The second request should be using a new socket.
1398 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1399 }
1400
[email protected]1c773ea12009-04-28 19:58:421401 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521402 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521403
wezca1070932016-05-26 20:30:521404 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251405 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521406
1407 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571408 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421409 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251410 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521411 }
1412}
[email protected]3d2a59b2008-09-26 19:44:251413
[email protected]a34f61ee2014-03-18 20:59:491414void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1415 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101416 const MockRead* read_failure,
1417 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491418 HttpRequestInfo request;
1419 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101420 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491421 request.load_flags = 0;
1422
vishal.b62985ca92015-04-17 08:45:511423 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491424 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091425 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491426
[email protected]09356c652014-03-25 15:36:101427 SSLSocketDataProvider ssl1(ASYNC, OK);
1428 SSLSocketDataProvider ssl2(ASYNC, OK);
1429 if (use_spdy) {
rdsmithebb50aa2015-11-12 03:44:381430 ssl1.SetNextProto(GetProtocol());
1431 ssl2.SetNextProto(GetProtocol());
[email protected]09356c652014-03-25 15:36:101432 }
1433 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1434 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491435
[email protected]09356c652014-03-25 15:36:101436 // SPDY versions of the request and response.
danakj1fd259a02016-04-16 03:17:091437 std::unique_ptr<SpdySerializedFrame> spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491438 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
danakj1fd259a02016-04-16 03:17:091439 std::unique_ptr<SpdySerializedFrame> spdy_response(
[email protected]09356c652014-03-25 15:36:101440 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:091441 std::unique_ptr<SpdySerializedFrame> spdy_data(
[email protected]09356c652014-03-25 15:36:101442 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491443
[email protected]09356c652014-03-25 15:36:101444 // HTTP/1.1 versions of the request and response.
1445 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1446 "Host: www.foo.com\r\n"
1447 "Connection: keep-alive\r\n\r\n";
1448 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1449 const char kHttpData[] = "hello";
1450
1451 std::vector<MockRead> data1_reads;
1452 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491453 if (write_failure) {
1454 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101455 data1_writes.push_back(*write_failure);
1456 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491457 } else {
1458 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101459 if (use_spdy) {
1460 data1_writes.push_back(CreateMockWrite(*spdy_request));
1461 } else {
1462 data1_writes.push_back(MockWrite(kHttpRequest));
1463 }
1464 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491465 }
1466
[email protected]09356c652014-03-25 15:36:101467 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1468 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491469 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1470
[email protected]09356c652014-03-25 15:36:101471 std::vector<MockRead> data2_reads;
1472 std::vector<MockWrite> data2_writes;
1473
1474 if (use_spdy) {
1475 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1476
1477 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1478 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1479 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1480 } else {
1481 data2_writes.push_back(
1482 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1483
1484 data2_reads.push_back(
1485 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1486 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1487 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1488 }
rch8e6c6c42015-05-01 14:05:131489 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1490 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491491 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1492
1493 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591494 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491495 // Wait for the preconnect to complete.
1496 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1497 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101498 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491499
1500 // Make the request.
1501 TestCompletionCallback callback;
1502
danakj1fd259a02016-04-16 03:17:091503 std::unique_ptr<HttpTransaction> trans(
[email protected]a34f61ee2014-03-18 20:59:491504 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1505
1506 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1507 EXPECT_EQ(ERR_IO_PENDING, rv);
1508
1509 rv = callback.WaitForResult();
1510 EXPECT_EQ(OK, rv);
1511
1512 LoadTimingInfo load_timing_info;
1513 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101514 TestLoadTimingNotReused(
1515 load_timing_info,
1516 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491517
1518 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521519 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491520
wezca1070932016-05-26 20:30:521521 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021522 if (response->was_fetched_via_spdy) {
1523 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1524 } else {
1525 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1526 }
[email protected]a34f61ee2014-03-18 20:59:491527
1528 std::string response_data;
1529 rv = ReadTransaction(trans.get(), &response_data);
1530 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101531 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491532}
1533
[email protected]23e482282013-06-14 16:08:021534TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231535 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061536 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511537 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1538}
1539
[email protected]23e482282013-06-14 16:08:021540TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061541 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511542 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251543}
1544
[email protected]23e482282013-06-14 16:08:021545TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061546 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511547 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251548}
1549
[email protected]d58ceea82014-06-04 10:55:541550// Make sure that on a 408 response (Request Timeout), the request is retried,
1551// if the socket was a reused keep alive socket.
1552TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1553 MockRead read_failure(SYNCHRONOUS,
1554 "HTTP/1.1 408 Request Timeout\r\n"
1555 "Connection: Keep-Alive\r\n"
1556 "Content-Length: 6\r\n\r\n"
1557 "Pickle");
1558 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1559}
1560
[email protected]a34f61ee2014-03-18 20:59:491561TEST_P(HttpNetworkTransactionTest,
1562 PreconnectErrorNotConnectedOnWrite) {
1563 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101564 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491565}
1566
1567TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1568 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101569 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491570}
1571
1572TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1573 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101574 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1575}
1576
1577TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1578 MockRead read_failure(ASYNC, OK); // EOF
1579 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1580}
1581
[email protected]d58ceea82014-06-04 10:55:541582// Make sure that on a 408 response (Request Timeout), the request is retried,
1583// if the socket was a preconnected (UNUSED_IDLE) socket.
1584TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1585 MockRead read_failure(SYNCHRONOUS,
1586 "HTTP/1.1 408 Request Timeout\r\n"
1587 "Connection: Keep-Alive\r\n"
1588 "Content-Length: 6\r\n\r\n"
1589 "Pickle");
1590 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1591 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1592}
1593
[email protected]09356c652014-03-25 15:36:101594TEST_P(HttpNetworkTransactionTest,
1595 SpdyPreconnectErrorNotConnectedOnWrite) {
1596 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1597 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1598}
1599
1600TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1601 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1602 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1603}
1604
1605TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1606 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1607 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1608}
1609
1610TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1611 MockRead read_failure(ASYNC, OK); // EOF
1612 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491613}
1614
[email protected]23e482282013-06-14 16:08:021615TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421616 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251617 request.method = "GET";
bncce36dca22015-04-21 22:11:231618 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251619 request.load_flags = 0;
1620
danakj1fd259a02016-04-16 03:17:091621 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1622 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411623 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271624
[email protected]3d2a59b2008-09-26 19:44:251625 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061626 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351627 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1628 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061629 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251630 };
[email protected]31a2bfe2010-02-09 08:03:391631 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071632 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251633
[email protected]49639fa2011-12-20 23:22:411634 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251635
[email protected]49639fa2011-12-20 23:22:411636 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421637 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251638
1639 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421640 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:591641
1642 IPEndPoint endpoint;
1643 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
1644 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251645}
1646
1647// What do various browsers do when the server closes a non-keepalive
1648// connection without sending any response header or body?
1649//
1650// IE7: error page
1651// Safari 3.1.2 (Windows): error page
1652// Firefox 3.0.1: blank page
1653// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421654// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1655// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021656TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251657 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061658 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351659 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1660 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061661 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251662 };
[email protected]31a2bfe2010-02-09 08:03:391663 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1664 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421665 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251666}
[email protected]038e9a32008-10-08 22:40:161667
[email protected]1826a402014-01-08 15:40:481668// Test that network access can be deferred and resumed.
1669TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1670 HttpRequestInfo request;
1671 request.method = "GET";
bncce36dca22015-04-21 22:11:231672 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481673 request.load_flags = 0;
1674
danakj1fd259a02016-04-16 03:17:091675 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1676 std::unique_ptr<HttpTransaction> trans(
[email protected]1826a402014-01-08 15:40:481677 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1678
1679 // Defer on OnBeforeNetworkStart.
1680 BeforeNetworkStartHandler net_start_handler(true); // defer
1681 trans->SetBeforeNetworkStartCallback(
1682 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1683 base::Unretained(&net_start_handler)));
1684
1685 MockRead data_reads[] = {
1686 MockRead("HTTP/1.0 200 OK\r\n"),
1687 MockRead("Content-Length: 5\r\n\r\n"),
1688 MockRead("hello"),
1689 MockRead(SYNCHRONOUS, 0),
1690 };
1691 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1692 session_deps_.socket_factory->AddSocketDataProvider(&data);
1693
1694 TestCompletionCallback callback;
1695
1696 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1697 EXPECT_EQ(ERR_IO_PENDING, rv);
1698 base::MessageLoop::current()->RunUntilIdle();
1699
1700 // Should have deferred for network start.
1701 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1702 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481703
1704 trans->ResumeNetworkStart();
1705 rv = callback.WaitForResult();
1706 EXPECT_EQ(OK, rv);
wezca1070932016-05-26 20:30:521707 EXPECT_TRUE(trans->GetResponseInfo());
[email protected]1826a402014-01-08 15:40:481708
1709 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1710 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1711 if (rv == ERR_IO_PENDING)
1712 rv = callback.WaitForResult();
1713 EXPECT_EQ(5, rv);
1714 trans.reset();
1715}
1716
1717// Test that network use can be deferred and canceled.
1718TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1719 HttpRequestInfo request;
1720 request.method = "GET";
bncce36dca22015-04-21 22:11:231721 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481722 request.load_flags = 0;
1723
danakj1fd259a02016-04-16 03:17:091724 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1725 std::unique_ptr<HttpTransaction> trans(
[email protected]1826a402014-01-08 15:40:481726 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1727
1728 // Defer on OnBeforeNetworkStart.
1729 BeforeNetworkStartHandler net_start_handler(true); // defer
1730 trans->SetBeforeNetworkStartCallback(
1731 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1732 base::Unretained(&net_start_handler)));
1733
1734 TestCompletionCallback callback;
1735
1736 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1737 EXPECT_EQ(ERR_IO_PENDING, rv);
1738 base::MessageLoop::current()->RunUntilIdle();
1739
1740 // Should have deferred for network start.
1741 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1742 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481743}
1744
[email protected]7a5378b2012-11-04 03:25:171745// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1746// tests. There was a bug causing HttpNetworkTransaction to hang in the
1747// destructor in such situations.
1748// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021749TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171750 HttpRequestInfo request;
1751 request.method = "GET";
bncce36dca22015-04-21 22:11:231752 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171753 request.load_flags = 0;
1754
danakj1fd259a02016-04-16 03:17:091755 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1756 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501757 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171758
1759 MockRead data_reads[] = {
1760 MockRead("HTTP/1.0 200 OK\r\n"),
1761 MockRead("Connection: keep-alive\r\n"),
1762 MockRead("Content-Length: 100\r\n\r\n"),
1763 MockRead("hello"),
1764 MockRead(SYNCHRONOUS, 0),
1765 };
1766 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071767 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171768
1769 TestCompletionCallback callback;
1770
1771 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1772 EXPECT_EQ(ERR_IO_PENDING, rv);
1773
1774 rv = callback.WaitForResult();
1775 EXPECT_EQ(OK, rv);
1776
1777 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501778 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171779 if (rv == ERR_IO_PENDING)
1780 rv = callback.WaitForResult();
1781 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501782 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171783 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1784
1785 trans.reset();
[email protected]2da659e2013-05-23 20:51:341786 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171787 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1788}
1789
[email protected]23e482282013-06-14 16:08:021790TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171791 HttpRequestInfo request;
1792 request.method = "GET";
bncce36dca22015-04-21 22:11:231793 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171794 request.load_flags = 0;
1795
danakj1fd259a02016-04-16 03:17:091796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1797 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501798 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171799
1800 MockRead data_reads[] = {
1801 MockRead("HTTP/1.0 200 OK\r\n"),
1802 MockRead("Connection: keep-alive\r\n"),
1803 MockRead("Content-Length: 100\r\n\r\n"),
1804 MockRead(SYNCHRONOUS, 0),
1805 };
1806 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071807 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171808
1809 TestCompletionCallback callback;
1810
1811 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1812 EXPECT_EQ(ERR_IO_PENDING, rv);
1813
1814 rv = callback.WaitForResult();
1815 EXPECT_EQ(OK, rv);
1816
1817 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501818 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171819 if (rv == ERR_IO_PENDING)
1820 rv = callback.WaitForResult();
1821 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1822
1823 trans.reset();
[email protected]2da659e2013-05-23 20:51:341824 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171825 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1826}
1827
[email protected]0b0bf032010-09-21 18:08:501828// Test that we correctly reuse a keep-alive connection after not explicitly
1829// reading the body.
[email protected]23e482282013-06-14 16:08:021830TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131831 HttpRequestInfo request;
1832 request.method = "GET";
1833 request.url = GURL("http://www.foo.com/");
1834 request.load_flags = 0;
1835
vishal.b62985ca92015-04-17 08:45:511836 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071837 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271839
mmenkecc2298e2015-12-07 18:20:181840 const char* request_data =
1841 "GET / HTTP/1.1\r\n"
1842 "Host: www.foo.com\r\n"
1843 "Connection: keep-alive\r\n\r\n";
1844 MockWrite data_writes[] = {
1845 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1846 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1847 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1848 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1849 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1850 };
1851
[email protected]0b0bf032010-09-21 18:08:501852 // Note that because all these reads happen in the same
1853 // StaticSocketDataProvider, it shows that the same socket is being reused for
1854 // all transactions.
mmenkecc2298e2015-12-07 18:20:181855 MockRead data_reads[] = {
1856 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1857 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1858 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1859 MockRead(ASYNC, 7,
1860 "HTTP/1.1 302 Found\r\n"
1861 "Content-Length: 0\r\n\r\n"),
1862 MockRead(ASYNC, 9,
1863 "HTTP/1.1 302 Found\r\n"
1864 "Content-Length: 5\r\n\r\n"
1865 "hello"),
1866 MockRead(ASYNC, 11,
1867 "HTTP/1.1 301 Moved Permanently\r\n"
1868 "Content-Length: 0\r\n\r\n"),
1869 MockRead(ASYNC, 13,
1870 "HTTP/1.1 301 Moved Permanently\r\n"
1871 "Content-Length: 5\r\n\r\n"
1872 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131873
mmenkecc2298e2015-12-07 18:20:181874 // In the next two rounds, IsConnectedAndIdle returns false, due to
1875 // the set_busy_before_sync_reads(true) call, while the
1876 // HttpNetworkTransaction is being shut down, but the socket is still
1877 // reuseable. See http://crbug.com/544255.
1878 MockRead(ASYNC, 15,
1879 "HTTP/1.1 200 Hunky-Dory\r\n"
1880 "Content-Length: 5\r\n\r\n"),
1881 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131882
mmenkecc2298e2015-12-07 18:20:181883 MockRead(ASYNC, 18,
1884 "HTTP/1.1 200 Hunky-Dory\r\n"
1885 "Content-Length: 5\r\n\r\n"
1886 "he"),
1887 MockRead(SYNCHRONOUS, 19, "llo"),
1888
1889 // The body of the final request is actually read.
1890 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1891 MockRead(ASYNC, 22, "hello"),
1892 };
1893 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1894 arraysize(data_writes));
1895 data.set_busy_before_sync_reads(true);
1896 session_deps_.socket_factory->AddSocketDataProvider(&data);
1897
1898 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501899 std::string response_lines[kNumUnreadBodies];
1900
avibf0746c2015-12-09 19:53:141901 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181902 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411903 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131904
danakj1fd259a02016-04-16 03:17:091905 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501906 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131907
[email protected]49639fa2011-12-20 23:22:411908 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
mmenkecc2298e2015-12-07 18:20:181909 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]fc31d6a42010-06-24 18:05:131910
[email protected]58e32bb2013-01-21 18:23:251911 LoadTimingInfo load_timing_info;
1912 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1913 if (i == 0) {
1914 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1915 first_socket_log_id = load_timing_info.socket_log_id;
1916 } else {
1917 TestLoadTimingReused(load_timing_info);
1918 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1919 }
1920
[email protected]fc31d6a42010-06-24 18:05:131921 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181922 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131923
mmenkecc2298e2015-12-07 18:20:181924 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501925 response_lines[i] = response->headers->GetStatusLine();
1926
mmenkecc2298e2015-12-07 18:20:181927 // Delete the transaction without reading the response bodies. Then spin
1928 // the message loop, so the response bodies are drained.
1929 trans.reset();
1930 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131931 }
[email protected]0b0bf032010-09-21 18:08:501932
1933 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181934 "HTTP/1.1 204 No Content",
1935 "HTTP/1.1 205 Reset Content",
1936 "HTTP/1.1 304 Not Modified",
1937 "HTTP/1.1 302 Found",
1938 "HTTP/1.1 302 Found",
1939 "HTTP/1.1 301 Moved Permanently",
1940 "HTTP/1.1 301 Moved Permanently",
1941 "HTTP/1.1 200 Hunky-Dory",
1942 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:501943 };
1944
mostynb91e0da982015-01-20 19:17:271945 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1946 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501947
1948 for (int i = 0; i < kNumUnreadBodies; ++i)
1949 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1950
[email protected]49639fa2011-12-20 23:22:411951 TestCompletionCallback callback;
danakj1fd259a02016-04-16 03:17:091952 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501953 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411954 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
mmenkecc2298e2015-12-07 18:20:181955 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]0b0bf032010-09-21 18:08:501956 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181957 ASSERT_TRUE(response);
1958 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501959 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1960 std::string response_data;
1961 rv = ReadTransaction(trans.get(), &response_data);
1962 EXPECT_EQ(OK, rv);
1963 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131964}
1965
[email protected]038e9a32008-10-08 22:40:161966// Test the request-challenge-retry sequence for basic auth.
1967// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021968TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421969 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161970 request.method = "GET";
bncce36dca22015-04-21 22:11:231971 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161972 request.load_flags = 0;
1973
vishal.b62985ca92015-04-17 08:45:511974 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071975 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:091976 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1977 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271979
[email protected]f9ee6b52008-11-08 06:46:231980 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231981 MockWrite(
1982 "GET / HTTP/1.1\r\n"
1983 "Host: www.example.org\r\n"
1984 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231985 };
1986
[email protected]038e9a32008-10-08 22:40:161987 MockRead data_reads1[] = {
1988 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1989 // Give a couple authenticate options (only the middle one is actually
1990 // supported).
[email protected]22927ad2009-09-21 19:56:191991 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161992 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1993 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1994 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1995 // Large content-length -- won't matter, as connection will be reset.
1996 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061997 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161998 };
1999
2000 // After calling trans->RestartWithAuth(), this is the request we should
2001 // be issuing -- the final header line contains the credentials.
2002 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232003 MockWrite(
2004 "GET / HTTP/1.1\r\n"
2005 "Host: www.example.org\r\n"
2006 "Connection: keep-alive\r\n"
2007 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162008 };
2009
2010 // Lastly, the server responds with the actual content.
2011 MockRead data_reads2[] = {
2012 MockRead("HTTP/1.0 200 OK\r\n"),
2013 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2014 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062015 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162016 };
2017
[email protected]31a2bfe2010-02-09 08:03:392018 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2019 data_writes1, arraysize(data_writes1));
2020 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2021 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072022 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2023 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162024
[email protected]49639fa2011-12-20 23:22:412025 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162026
[email protected]49639fa2011-12-20 23:22:412027 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422028 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162029
2030 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422031 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162032
[email protected]58e32bb2013-01-21 18:23:252033 LoadTimingInfo load_timing_info1;
2034 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2035 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2036
sclittlefb249892015-09-10 21:33:222037 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2038 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2039 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:192040 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2041
[email protected]1c773ea12009-04-28 19:58:422042 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522043 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042044 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162045
[email protected]49639fa2011-12-20 23:22:412046 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162047
[email protected]49639fa2011-12-20 23:22:412048 rv = trans->RestartWithAuth(
2049 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422050 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162051
2052 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422053 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162054
[email protected]58e32bb2013-01-21 18:23:252055 LoadTimingInfo load_timing_info2;
2056 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2057 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2058 // The load timing after restart should have a new socket ID, and times after
2059 // those of the first load timing.
2060 EXPECT_LE(load_timing_info1.receive_headers_end,
2061 load_timing_info2.connect_timing.connect_start);
2062 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2063
sclittlefb249892015-09-10 21:33:222064 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2065 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2066 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
[email protected]b8015c42013-12-24 15:18:192067 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2068
[email protected]038e9a32008-10-08 22:40:162069 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522070 ASSERT_TRUE(response);
2071 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162072 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162073}
2074
ttuttled9dbc652015-09-29 20:00:592075// Test the request-challenge-retry sequence for basic auth.
2076// (basic auth is the easiest to mock, because it has no randomness).
2077TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
2078 HttpRequestInfo request;
2079 request.method = "GET";
2080 request.url = GURL("http://www.example.org/");
2081 request.load_flags = 0;
2082
2083 TestNetLog log;
2084 MockHostResolver* resolver = new MockHostResolver();
2085 session_deps_.net_log = &log;
2086 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092087 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
2088 std::unique_ptr<HttpTransaction> trans(
ttuttled9dbc652015-09-29 20:00:592089 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2090
2091 resolver->rules()->ClearRules();
2092 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2093
2094 MockWrite data_writes1[] = {
2095 MockWrite("GET / HTTP/1.1\r\n"
2096 "Host: www.example.org\r\n"
2097 "Connection: keep-alive\r\n\r\n"),
2098 };
2099
2100 MockRead data_reads1[] = {
2101 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2102 // Give a couple authenticate options (only the middle one is actually
2103 // supported).
2104 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2105 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2106 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2107 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2108 // Large content-length -- won't matter, as connection will be reset.
2109 MockRead("Content-Length: 10000\r\n\r\n"),
2110 MockRead(SYNCHRONOUS, ERR_FAILED),
2111 };
2112
2113 // After calling trans->RestartWithAuth(), this is the request we should
2114 // be issuing -- the final header line contains the credentials.
2115 MockWrite data_writes2[] = {
2116 MockWrite("GET / HTTP/1.1\r\n"
2117 "Host: www.example.org\r\n"
2118 "Connection: keep-alive\r\n"
2119 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2120 };
2121
2122 // Lastly, the server responds with the actual content.
2123 MockRead data_reads2[] = {
2124 MockRead("HTTP/1.0 200 OK\r\n"),
2125 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2126 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2127 };
2128
2129 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2130 data_writes1, arraysize(data_writes1));
2131 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2132 data_writes2, arraysize(data_writes2));
2133 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2134 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2135
2136 TestCompletionCallback callback1;
2137
2138 EXPECT_EQ(OK, callback1.GetResult(trans->Start(&request, callback1.callback(),
2139 BoundNetLog())));
2140
2141 LoadTimingInfo load_timing_info1;
2142 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2143 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2144
2145 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2146 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2147 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
2148 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2149
2150 const HttpResponseInfo* response = trans->GetResponseInfo();
2151 ASSERT_TRUE(response);
2152 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2153
2154 IPEndPoint endpoint;
2155 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2156 ASSERT_FALSE(endpoint.address().empty());
2157 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2158
2159 resolver->rules()->ClearRules();
2160 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2161
2162 TestCompletionCallback callback2;
2163
2164 EXPECT_EQ(OK, callback2.GetResult(trans->RestartWithAuth(
2165 AuthCredentials(kFoo, kBar), callback2.callback())));
2166
2167 LoadTimingInfo load_timing_info2;
2168 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2169 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2170 // The load timing after restart should have a new socket ID, and times after
2171 // those of the first load timing.
2172 EXPECT_LE(load_timing_info1.receive_headers_end,
2173 load_timing_info2.connect_timing.connect_start);
2174 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2175
2176 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2177 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2178 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
2179 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2180
2181 response = trans->GetResponseInfo();
2182 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522183 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592184 EXPECT_EQ(100, response->headers->GetContentLength());
2185
2186 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2187 ASSERT_FALSE(endpoint.address().empty());
2188 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2189}
2190
[email protected]23e482282013-06-14 16:08:022191TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462192 HttpRequestInfo request;
2193 request.method = "GET";
bncce36dca22015-04-21 22:11:232194 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292195 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462196
danakj1fd259a02016-04-16 03:17:092197 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2198 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272200
[email protected]861fcd52009-08-26 02:33:462201 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232202 MockWrite(
2203 "GET / HTTP/1.1\r\n"
2204 "Host: www.example.org\r\n"
2205 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462206 };
2207
2208 MockRead data_reads[] = {
2209 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2210 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2211 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2212 // Large content-length -- won't matter, as connection will be reset.
2213 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062214 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462215 };
2216
[email protected]31a2bfe2010-02-09 08:03:392217 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2218 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072219 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412220 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462221
[email protected]49639fa2011-12-20 23:22:412222 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462223 EXPECT_EQ(ERR_IO_PENDING, rv);
2224
2225 rv = callback.WaitForResult();
2226 EXPECT_EQ(0, rv);
2227
sclittlefb249892015-09-10 21:33:222228 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2229 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2230 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
[email protected]b8015c42013-12-24 15:18:192231 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2232
[email protected]861fcd52009-08-26 02:33:462233 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522234 ASSERT_TRUE(response);
2235 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462236}
2237
[email protected]2d2697f92009-02-18 21:00:322238// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2239// connection.
[email protected]23e482282013-06-14 16:08:022240TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182241 // On the second pass, the body read of the auth challenge is synchronous, so
2242 // IsConnectedAndIdle returns false. The socket should still be drained and
2243 // reused. See http://crbug.com/544255.
2244 for (int i = 0; i < 2; ++i) {
2245 HttpRequestInfo request;
2246 request.method = "GET";
2247 request.url = GURL("http://www.example.org/");
2248 request.load_flags = 0;
[email protected]2d2697f92009-02-18 21:00:322249
mmenkecc2298e2015-12-07 18:20:182250 TestNetLog log;
2251 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092252 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272253
mmenkecc2298e2015-12-07 18:20:182254 MockWrite data_writes[] = {
2255 MockWrite(ASYNC, 0,
2256 "GET / HTTP/1.1\r\n"
2257 "Host: www.example.org\r\n"
2258 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322259
mmenkecc2298e2015-12-07 18:20:182260 // After calling trans->RestartWithAuth(), this is the request we should
2261 // be issuing -- the final header line contains the credentials.
2262 MockWrite(ASYNC, 6,
2263 "GET / HTTP/1.1\r\n"
2264 "Host: www.example.org\r\n"
2265 "Connection: keep-alive\r\n"
2266 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2267 };
[email protected]2d2697f92009-02-18 21:00:322268
mmenkecc2298e2015-12-07 18:20:182269 MockRead data_reads[] = {
2270 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2271 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2272 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2273 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2274 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322275
mmenkecc2298e2015-12-07 18:20:182276 // Lastly, the server responds with the actual content.
2277 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2278 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2279 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2280 MockRead(ASYNC, 10, "Hello"),
2281 };
[email protected]2d2697f92009-02-18 21:00:322282
mmenkecc2298e2015-12-07 18:20:182283 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2284 arraysize(data_writes));
2285 data.set_busy_before_sync_reads(true);
2286 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462287
mmenkecc2298e2015-12-07 18:20:182288 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322289
danakj1fd259a02016-04-16 03:17:092290 std::unique_ptr<HttpTransaction> trans(
mmenkecc2298e2015-12-07 18:20:182291 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2292 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2293 ASSERT_EQ(OK, callback1.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:322294
mmenkecc2298e2015-12-07 18:20:182295 LoadTimingInfo load_timing_info1;
2296 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2297 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322298
mmenkecc2298e2015-12-07 18:20:182299 const HttpResponseInfo* response = trans->GetResponseInfo();
2300 ASSERT_TRUE(response);
2301 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322302
mmenkecc2298e2015-12-07 18:20:182303 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252304
mmenkecc2298e2015-12-07 18:20:182305 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
2306 callback2.callback());
2307 ASSERT_EQ(OK, callback2.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:322308
mmenkecc2298e2015-12-07 18:20:182309 LoadTimingInfo load_timing_info2;
2310 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2311 TestLoadTimingReused(load_timing_info2);
2312 // The load timing after restart should have the same socket ID, and times
2313 // those of the first load timing.
2314 EXPECT_LE(load_timing_info1.receive_headers_end,
2315 load_timing_info2.send_start);
2316 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322317
mmenkecc2298e2015-12-07 18:20:182318 response = trans->GetResponseInfo();
2319 ASSERT_TRUE(response);
2320 EXPECT_FALSE(response->auth_challenge);
2321 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322322
mmenkecc2298e2015-12-07 18:20:182323 std::string response_data;
2324 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]2d2697f92009-02-18 21:00:322325
mmenkecc2298e2015-12-07 18:20:182326 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2327 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2328 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
2329 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2330 }
[email protected]2d2697f92009-02-18 21:00:322331}
2332
2333// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2334// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022335TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422336 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322337 request.method = "GET";
bncce36dca22015-04-21 22:11:232338 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322339 request.load_flags = 0;
2340
danakj1fd259a02016-04-16 03:17:092341 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272342
[email protected]2d2697f92009-02-18 21:00:322343 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232344 MockWrite(
2345 "GET / HTTP/1.1\r\n"
2346 "Host: www.example.org\r\n"
2347 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322348
bncce36dca22015-04-21 22:11:232349 // After calling trans->RestartWithAuth(), this is the request we should
2350 // be issuing -- the final header line contains the credentials.
2351 MockWrite(
2352 "GET / HTTP/1.1\r\n"
2353 "Host: www.example.org\r\n"
2354 "Connection: keep-alive\r\n"
2355 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322356 };
2357
[email protected]2d2697f92009-02-18 21:00:322358 MockRead data_reads1[] = {
2359 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2360 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312361 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322362
2363 // Lastly, the server responds with the actual content.
2364 MockRead("HTTP/1.1 200 OK\r\n"),
2365 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502366 MockRead("Content-Length: 5\r\n\r\n"),
2367 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322368 };
2369
[email protected]2d0a4f92011-05-05 16:38:462370 // An incorrect reconnect would cause this to be read.
2371 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062372 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462373 };
2374
[email protected]31a2bfe2010-02-09 08:03:392375 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2376 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462377 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2378 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072379 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2380 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322381
[email protected]49639fa2011-12-20 23:22:412382 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322383
danakj1fd259a02016-04-16 03:17:092384 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502385 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412386 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422387 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322388
2389 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422390 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322391
[email protected]1c773ea12009-04-28 19:58:422392 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522393 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042394 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322395
[email protected]49639fa2011-12-20 23:22:412396 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322397
[email protected]49639fa2011-12-20 23:22:412398 rv = trans->RestartWithAuth(
2399 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422400 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322401
2402 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422403 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322404
2405 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522406 ASSERT_TRUE(response);
2407 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502408 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322409}
2410
2411// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2412// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022413TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422414 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322415 request.method = "GET";
bncce36dca22015-04-21 22:11:232416 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322417 request.load_flags = 0;
2418
danakj1fd259a02016-04-16 03:17:092419 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272420
[email protected]2d2697f92009-02-18 21:00:322421 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232422 MockWrite(
2423 "GET / HTTP/1.1\r\n"
2424 "Host: www.example.org\r\n"
2425 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322426
bncce36dca22015-04-21 22:11:232427 // After calling trans->RestartWithAuth(), this is the request we should
2428 // be issuing -- the final header line contains the credentials.
2429 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]2d2697f92009-02-18 21:00:322434 };
2435
2436 // Respond with 5 kb of response body.
2437 std::string large_body_string("Unauthorized");
2438 large_body_string.append(5 * 1024, ' ');
2439 large_body_string.append("\r\n");
2440
2441 MockRead data_reads1[] = {
2442 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2443 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2444 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2445 // 5134 = 12 + 5 * 1024 + 2
2446 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062447 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322448
2449 // Lastly, the server responds with the actual content.
2450 MockRead("HTTP/1.1 200 OK\r\n"),
2451 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502452 MockRead("Content-Length: 5\r\n\r\n"),
2453 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322454 };
2455
[email protected]2d0a4f92011-05-05 16:38:462456 // An incorrect reconnect would cause this to be read.
2457 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062458 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462459 };
2460
[email protected]31a2bfe2010-02-09 08:03:392461 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2462 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462463 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2464 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072465 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2466 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322467
[email protected]49639fa2011-12-20 23:22:412468 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322469
danakj1fd259a02016-04-16 03:17:092470 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502471 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412472 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422473 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322474
2475 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422476 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322477
[email protected]1c773ea12009-04-28 19:58:422478 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522479 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042480 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322481
[email protected]49639fa2011-12-20 23:22:412482 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322483
[email protected]49639fa2011-12-20 23:22:412484 rv = trans->RestartWithAuth(
2485 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422486 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322487
2488 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422489 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322490
2491 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522492 ASSERT_TRUE(response);
2493 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502494 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322495}
2496
2497// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312498// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022499TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312500 HttpRequestInfo request;
2501 request.method = "GET";
bncce36dca22015-04-21 22:11:232502 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312503 request.load_flags = 0;
2504
danakj1fd259a02016-04-16 03:17:092505 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272506
[email protected]11203f012009-11-12 23:02:312507 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232508 MockWrite(
2509 "GET / HTTP/1.1\r\n"
2510 "Host: www.example.org\r\n"
2511 "Connection: keep-alive\r\n\r\n"),
2512 // This simulates the seemingly successful write to a closed connection
2513 // if the bug is not fixed.
2514 MockWrite(
2515 "GET / HTTP/1.1\r\n"
2516 "Host: www.example.org\r\n"
2517 "Connection: keep-alive\r\n"
2518 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312519 };
2520
2521 MockRead data_reads1[] = {
2522 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2523 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2524 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2525 MockRead("Content-Length: 14\r\n\r\n"),
2526 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062527 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312528 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062529 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312530 };
2531
2532 // After calling trans->RestartWithAuth(), this is the request we should
2533 // be issuing -- the final header line contains the credentials.
2534 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232535 MockWrite(
2536 "GET / HTTP/1.1\r\n"
2537 "Host: www.example.org\r\n"
2538 "Connection: keep-alive\r\n"
2539 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312540 };
2541
2542 // Lastly, the server responds with the actual content.
2543 MockRead data_reads2[] = {
2544 MockRead("HTTP/1.1 200 OK\r\n"),
2545 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502546 MockRead("Content-Length: 5\r\n\r\n"),
2547 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312548 };
2549
[email protected]31a2bfe2010-02-09 08:03:392550 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2551 data_writes1, arraysize(data_writes1));
2552 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2553 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072554 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2555 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312556
[email protected]49639fa2011-12-20 23:22:412557 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312558
danakj1fd259a02016-04-16 03:17:092559 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502560 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412561 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312562 EXPECT_EQ(ERR_IO_PENDING, rv);
2563
2564 rv = callback1.WaitForResult();
2565 EXPECT_EQ(OK, rv);
2566
2567 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522568 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042569 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312570
[email protected]49639fa2011-12-20 23:22:412571 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312572
[email protected]49639fa2011-12-20 23:22:412573 rv = trans->RestartWithAuth(
2574 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312575 EXPECT_EQ(ERR_IO_PENDING, rv);
2576
2577 rv = callback2.WaitForResult();
2578 EXPECT_EQ(OK, rv);
2579
2580 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522581 ASSERT_TRUE(response);
2582 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502583 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312584}
2585
[email protected]394816e92010-08-03 07:38:592586// Test the request-challenge-retry sequence for basic auth, over a connection
2587// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012588TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2589 HttpRequestInfo request;
2590 request.method = "GET";
bncce36dca22015-04-21 22:11:232591 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012592 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292593 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012594
2595 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032596 session_deps_.proxy_service =
2597 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512598 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012599 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092600 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012601
2602 // Since we have proxy, should try to establish tunnel.
2603 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542604 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172605 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542606 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012607 };
2608
mmenkee71e15332015-10-07 16:39:542609 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012610 // connection.
2611 MockRead data_reads1[] = {
2612 // No credentials.
2613 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2614 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542615 };
ttuttle34f63b52015-03-05 04:33:012616
mmenkee71e15332015-10-07 16:39:542617 // Since the first connection couldn't be reused, need to establish another
2618 // once given credentials.
2619 MockWrite data_writes2[] = {
2620 // After calling trans->RestartWithAuth(), this is the request we should
2621 // be issuing -- the final header line contains the credentials.
2622 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172623 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542624 "Proxy-Connection: keep-alive\r\n"
2625 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2626
2627 MockWrite("GET / HTTP/1.1\r\n"
2628 "Host: www.example.org\r\n"
2629 "Connection: keep-alive\r\n\r\n"),
2630 };
2631
2632 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012633 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2634
2635 MockRead("HTTP/1.1 200 OK\r\n"),
2636 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2637 MockRead("Content-Length: 5\r\n\r\n"),
2638 MockRead(SYNCHRONOUS, "hello"),
2639 };
2640
2641 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2642 data_writes1, arraysize(data_writes1));
2643 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542644 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2645 data_writes2, arraysize(data_writes2));
2646 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012647 SSLSocketDataProvider ssl(ASYNC, OK);
2648 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2649
2650 TestCompletionCallback callback1;
2651
danakj1fd259a02016-04-16 03:17:092652 std::unique_ptr<HttpTransaction> trans(
ttuttle34f63b52015-03-05 04:33:012653 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2654
2655 int rv = trans->Start(&request, callback1.callback(), log.bound());
2656 EXPECT_EQ(ERR_IO_PENDING, rv);
2657
2658 rv = callback1.WaitForResult();
2659 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462660 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012661 log.GetEntries(&entries);
2662 size_t pos = ExpectLogContainsSomewhere(
2663 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2664 NetLog::PHASE_NONE);
2665 ExpectLogContainsSomewhere(
2666 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2667 NetLog::PHASE_NONE);
2668
2669 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522670 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012671 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522672 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012673 EXPECT_EQ(407, response->headers->response_code());
2674 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2675 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2676
2677 LoadTimingInfo load_timing_info;
2678 // CONNECT requests and responses are handled at the connect job level, so
2679 // the transaction does not yet have a connection.
2680 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2681
2682 TestCompletionCallback callback2;
2683
2684 rv =
2685 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2686 EXPECT_EQ(ERR_IO_PENDING, rv);
2687
2688 rv = callback2.WaitForResult();
2689 EXPECT_EQ(OK, rv);
2690
2691 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522692 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012693
2694 EXPECT_TRUE(response->headers->IsKeepAlive());
2695 EXPECT_EQ(200, response->headers->response_code());
2696 EXPECT_EQ(5, response->headers->GetContentLength());
2697 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2698
2699 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:522700 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:012701
2702 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2703 TestLoadTimingNotReusedWithPac(load_timing_info,
2704 CONNECT_TIMING_HAS_SSL_TIMES);
2705
2706 trans.reset();
2707 session->CloseAllConnections();
2708}
2709
2710// Test the request-challenge-retry sequence for basic auth, over a connection
2711// that requires a restart when setting up an SSL tunnel.
2712TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592713 HttpRequestInfo request;
2714 request.method = "GET";
bncce36dca22015-04-21 22:11:232715 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592716 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292717 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592718
[email protected]cb9bf6ca2011-01-28 13:15:272719 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032720 session_deps_.proxy_service =
2721 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512722 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072723 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092724 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272725
[email protected]394816e92010-08-03 07:38:592726 // Since we have proxy, should try to establish tunnel.
2727 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542728 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172729 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542730 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112731 };
2732
mmenkee71e15332015-10-07 16:39:542733 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:082734 // connection.
2735 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:542736 // No credentials.
2737 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2738 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2739 MockRead("Proxy-Connection: close\r\n\r\n"),
2740 };
mmenkee0b5c882015-08-26 20:29:112741
mmenkee71e15332015-10-07 16:39:542742 MockWrite data_writes2[] = {
2743 // After calling trans->RestartWithAuth(), this is the request we should
2744 // be issuing -- the final header line contains the credentials.
2745 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172746 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542747 "Proxy-Connection: keep-alive\r\n"
2748 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:082749
mmenkee71e15332015-10-07 16:39:542750 MockWrite("GET / HTTP/1.1\r\n"
2751 "Host: www.example.org\r\n"
2752 "Connection: keep-alive\r\n\r\n"),
2753 };
2754
2755 MockRead data_reads2[] = {
2756 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2757
2758 MockRead("HTTP/1.1 200 OK\r\n"),
2759 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2760 MockRead("Content-Length: 5\r\n\r\n"),
2761 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592762 };
2763
2764 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2765 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072766 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542767 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2768 data_writes2, arraysize(data_writes2));
2769 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:062770 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072771 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592772
[email protected]49639fa2011-12-20 23:22:412773 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592774
danakj1fd259a02016-04-16 03:17:092775 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502776 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502777
[email protected]49639fa2011-12-20 23:22:412778 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592779 EXPECT_EQ(ERR_IO_PENDING, rv);
2780
2781 rv = callback1.WaitForResult();
2782 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462783 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402784 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592785 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402786 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592787 NetLog::PHASE_NONE);
2788 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402789 entries, pos,
[email protected]394816e92010-08-03 07:38:592790 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2791 NetLog::PHASE_NONE);
2792
2793 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522794 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012795 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522796 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:592797 EXPECT_EQ(407, response->headers->response_code());
2798 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042799 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592800
[email protected]029c83b62013-01-24 05:28:202801 LoadTimingInfo load_timing_info;
2802 // CONNECT requests and responses are handled at the connect job level, so
2803 // the transaction does not yet have a connection.
2804 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2805
[email protected]49639fa2011-12-20 23:22:412806 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592807
[email protected]49639fa2011-12-20 23:22:412808 rv = trans->RestartWithAuth(
2809 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592810 EXPECT_EQ(ERR_IO_PENDING, rv);
2811
2812 rv = callback2.WaitForResult();
2813 EXPECT_EQ(OK, rv);
2814
2815 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522816 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:592817
2818 EXPECT_TRUE(response->headers->IsKeepAlive());
2819 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502820 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592821 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2822
2823 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:522824 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502825
[email protected]029c83b62013-01-24 05:28:202826 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2827 TestLoadTimingNotReusedWithPac(load_timing_info,
2828 CONNECT_TIMING_HAS_SSL_TIMES);
2829
[email protected]0b0bf032010-09-21 18:08:502830 trans.reset();
[email protected]102e27c2011-02-23 01:01:312831 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592832}
2833
[email protected]11203f012009-11-12 23:02:312834// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012835// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2836TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:232837 // On the second pass, the body read of the auth challenge is synchronous, so
2838 // IsConnectedAndIdle returns false. The socket should still be drained and
2839 // reused. See http://crbug.com/544255.
2840 for (int i = 0; i < 2; ++i) {
2841 HttpRequestInfo request;
2842 request.method = "GET";
2843 request.url = GURL("https://www.example.org/");
2844 // Ensure that proxy authentication is attempted even
2845 // when the no authentication data flag is set.
2846 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012847
mmenked39192ee2015-12-09 00:57:232848 // Configure against proxy server "myproxy:70".
2849 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
2850 BoundTestNetLog log;
2851 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092852 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012853
danakj1fd259a02016-04-16 03:17:092854 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:232855 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ttuttle34f63b52015-03-05 04:33:012856
mmenked39192ee2015-12-09 00:57:232857 // Since we have proxy, should try to establish tunnel.
2858 MockWrite data_writes1[] = {
2859 MockWrite(ASYNC, 0,
2860 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2861 "Host: www.example.org:443\r\n"
2862 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012863
mmenked39192ee2015-12-09 00:57:232864 // After calling trans->RestartWithAuth(), this is the request we should
2865 // be issuing -- the final header line contains the credentials.
2866 MockWrite(ASYNC, 3,
2867 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2868 "Host: www.example.org:443\r\n"
2869 "Proxy-Connection: keep-alive\r\n"
2870 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2871 };
ttuttle34f63b52015-03-05 04:33:012872
mmenked39192ee2015-12-09 00:57:232873 // The proxy responds to the connect with a 407, using a persistent
2874 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2875 MockRead data_reads1[] = {
2876 // No credentials.
2877 MockRead(ASYNC, 1,
2878 "HTTP/1.0 407 Proxy Authentication Required\r\n"
2879 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
2880 "Proxy-Connection: keep-alive\r\n"
2881 "Content-Length: 10\r\n\r\n"),
2882 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:012883
mmenked39192ee2015-12-09 00:57:232884 // Wrong credentials (wrong password).
2885 MockRead(ASYNC, 4,
2886 "HTTP/1.0 407 Proxy Authentication Required\r\n"
2887 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
2888 "Proxy-Connection: keep-alive\r\n"
2889 "Content-Length: 10\r\n\r\n"),
2890 // No response body because the test stops reading here.
2891 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
2892 };
ttuttle34f63b52015-03-05 04:33:012893
mmenked39192ee2015-12-09 00:57:232894 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
2895 arraysize(data_writes1));
2896 data1.set_busy_before_sync_reads(true);
2897 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:012898
mmenked39192ee2015-12-09 00:57:232899 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:012900
mmenked39192ee2015-12-09 00:57:232901 int rv = trans->Start(&request, callback1.callback(), log.bound());
2902 EXPECT_EQ(OK, callback1.GetResult(rv));
ttuttle34f63b52015-03-05 04:33:012903
mmenked39192ee2015-12-09 00:57:232904 TestNetLogEntry::List entries;
2905 log.GetEntries(&entries);
2906 size_t pos = ExpectLogContainsSomewhere(
2907 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2908 NetLog::PHASE_NONE);
2909 ExpectLogContainsSomewhere(
2910 entries, pos,
2911 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2912 NetLog::PHASE_NONE);
ttuttle34f63b52015-03-05 04:33:012913
mmenked39192ee2015-12-09 00:57:232914 const HttpResponseInfo* response = trans->GetResponseInfo();
2915 ASSERT_TRUE(response);
2916 ASSERT_TRUE(response->headers);
2917 EXPECT_TRUE(response->headers->IsKeepAlive());
2918 EXPECT_EQ(407, response->headers->response_code());
2919 EXPECT_EQ(10, response->headers->GetContentLength());
2920 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2921 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:012922
mmenked39192ee2015-12-09 00:57:232923 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:012924
mmenked39192ee2015-12-09 00:57:232925 // Wrong password (should be "bar").
2926 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
2927 callback2.callback());
2928 EXPECT_EQ(OK, callback2.GetResult(rv));
ttuttle34f63b52015-03-05 04:33:012929
mmenked39192ee2015-12-09 00:57:232930 response = trans->GetResponseInfo();
2931 ASSERT_TRUE(response);
2932 ASSERT_TRUE(response->headers);
2933 EXPECT_TRUE(response->headers->IsKeepAlive());
2934 EXPECT_EQ(407, response->headers->response_code());
2935 EXPECT_EQ(10, response->headers->GetContentLength());
2936 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2937 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:012938
mmenked39192ee2015-12-09 00:57:232939 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2940 // out of scope.
2941 session->CloseAllConnections();
2942 }
ttuttle34f63b52015-03-05 04:33:012943}
2944
2945// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2946// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2947TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:232948 // On the second pass, the body read of the auth challenge is synchronous, so
2949 // IsConnectedAndIdle returns false. The socket should still be drained and
2950 // reused. See http://crbug.com/544255.
2951 for (int i = 0; i < 2; ++i) {
2952 HttpRequestInfo request;
2953 request.method = "GET";
2954 request.url = GURL("https://www.example.org/");
2955 // Ensure that proxy authentication is attempted even
2956 // when the no authentication data flag is set.
2957 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
2958
2959 // Configure against proxy server "myproxy:70".
2960 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
2961 BoundTestNetLog log;
2962 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092963 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:232964
danakj1fd259a02016-04-16 03:17:092965 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:232966 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2967
2968 // Since we have proxy, should try to establish tunnel.
2969 MockWrite data_writes1[] = {
2970 MockWrite(ASYNC, 0,
2971 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2972 "Host: www.example.org:443\r\n"
2973 "Proxy-Connection: keep-alive\r\n\r\n"),
2974
2975 // After calling trans->RestartWithAuth(), this is the request we should
2976 // be issuing -- the final header line contains the credentials.
2977 MockWrite(ASYNC, 3,
2978 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2979 "Host: www.example.org:443\r\n"
2980 "Proxy-Connection: keep-alive\r\n"
2981 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2982 };
2983
2984 // The proxy responds to the connect with a 407, using a persistent
2985 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2986 MockRead data_reads1[] = {
2987 // No credentials.
2988 MockRead(ASYNC, 1,
2989 "HTTP/1.1 407 Proxy Authentication Required\r\n"
2990 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
2991 "Content-Length: 10\r\n\r\n"),
2992 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
2993
2994 // Wrong credentials (wrong password).
2995 MockRead(ASYNC, 4,
2996 "HTTP/1.1 407 Proxy Authentication Required\r\n"
2997 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
2998 "Content-Length: 10\r\n\r\n"),
2999 // No response body because the test stops reading here.
3000 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3001 };
3002
3003 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3004 arraysize(data_writes1));
3005 data1.set_busy_before_sync_reads(true);
3006 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3007
3008 TestCompletionCallback callback1;
3009
3010 int rv = trans->Start(&request, callback1.callback(), log.bound());
3011 EXPECT_EQ(OK, callback1.GetResult(rv));
3012
3013 TestNetLogEntry::List entries;
3014 log.GetEntries(&entries);
3015 size_t pos = ExpectLogContainsSomewhere(
3016 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3017 NetLog::PHASE_NONE);
3018 ExpectLogContainsSomewhere(
3019 entries, pos,
3020 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3021 NetLog::PHASE_NONE);
3022
3023 const HttpResponseInfo* response = trans->GetResponseInfo();
3024 ASSERT_TRUE(response);
3025 ASSERT_TRUE(response->headers);
3026 EXPECT_TRUE(response->headers->IsKeepAlive());
3027 EXPECT_EQ(407, response->headers->response_code());
3028 EXPECT_EQ(10, response->headers->GetContentLength());
3029 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3030 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3031
3032 TestCompletionCallback callback2;
3033
3034 // Wrong password (should be "bar").
3035 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
3036 callback2.callback());
3037 EXPECT_EQ(OK, callback2.GetResult(rv));
3038
3039 response = trans->GetResponseInfo();
3040 ASSERT_TRUE(response);
3041 ASSERT_TRUE(response->headers);
3042 EXPECT_TRUE(response->headers->IsKeepAlive());
3043 EXPECT_EQ(407, response->headers->response_code());
3044 EXPECT_EQ(10, response->headers->GetContentLength());
3045 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3046 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3047
3048 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3049 // out of scope.
3050 session->CloseAllConnections();
3051 }
3052}
3053
3054// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3055// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3056// the case the server sends extra data on the original socket, so it can't be
3057// reused.
3058TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273059 HttpRequestInfo request;
3060 request.method = "GET";
bncce36dca22015-04-21 22:11:233061 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273062 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293063 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273064
[email protected]2d2697f92009-02-18 21:00:323065 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233066 session_deps_.proxy_service =
3067 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513068 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073069 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093070 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323071
[email protected]2d2697f92009-02-18 21:00:323072 // Since we have proxy, should try to establish tunnel.
3073 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233074 MockWrite(ASYNC, 0,
3075 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173076 "Host: www.example.org:443\r\n"
3077 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233078 };
[email protected]2d2697f92009-02-18 21:00:323079
mmenked39192ee2015-12-09 00:57:233080 // The proxy responds to the connect with a 407, using a persistent, but sends
3081 // extra data, so the socket cannot be reused.
3082 MockRead data_reads1[] = {
3083 // No credentials.
3084 MockRead(ASYNC, 1,
3085 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3086 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3087 "Content-Length: 10\r\n\r\n"),
3088 MockRead(SYNCHRONOUS, 2, "0123456789"),
3089 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3090 };
3091
3092 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233093 // After calling trans->RestartWithAuth(), this is the request we should
3094 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233095 MockWrite(ASYNC, 0,
3096 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173097 "Host: www.example.org:443\r\n"
3098 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233099 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3100
3101 MockWrite(ASYNC, 2,
3102 "GET / HTTP/1.1\r\n"
3103 "Host: www.example.org\r\n"
3104 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323105 };
3106
mmenked39192ee2015-12-09 00:57:233107 MockRead data_reads2[] = {
3108 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323109
mmenked39192ee2015-12-09 00:57:233110 MockRead(ASYNC, 3,
3111 "HTTP/1.1 200 OK\r\n"
3112 "Content-Type: text/html; charset=iso-8859-1\r\n"
3113 "Content-Length: 5\r\n\r\n"),
3114 // No response body because the test stops reading here.
3115 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323116 };
3117
mmenked39192ee2015-12-09 00:57:233118 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3119 arraysize(data_writes1));
3120 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073121 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233122 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3123 arraysize(data_writes2));
3124 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3125 SSLSocketDataProvider ssl(ASYNC, OK);
3126 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323127
[email protected]49639fa2011-12-20 23:22:413128 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323129
danakj1fd259a02016-04-16 03:17:093130 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:233131 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:323132
mmenked39192ee2015-12-09 00:57:233133 int rv = trans->Start(&request, callback1.callback(), log.bound());
3134 EXPECT_EQ(OK, callback1.GetResult(rv));
3135
mmenke43758e62015-05-04 21:09:463136 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403137 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393138 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403139 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:393140 NetLog::PHASE_NONE);
3141 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403142 entries, pos,
[email protected]dbb83db2010-05-11 18:13:393143 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3144 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:323145
[email protected]1c773ea12009-04-28 19:58:423146 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243147 ASSERT_TRUE(response);
3148 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323149 EXPECT_TRUE(response->headers->IsKeepAlive());
3150 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423151 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043152 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323153
mmenked39192ee2015-12-09 00:57:233154 LoadTimingInfo load_timing_info;
3155 // CONNECT requests and responses are handled at the connect job level, so
3156 // the transaction does not yet have a connection.
3157 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3158
[email protected]49639fa2011-12-20 23:22:413159 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323160
mmenked39192ee2015-12-09 00:57:233161 rv =
3162 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3163 EXPECT_EQ(OK, callback2.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:323164
[email protected]2d2697f92009-02-18 21:00:323165 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233166 EXPECT_EQ(200, response->headers->response_code());
3167 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423168 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133169
mmenked39192ee2015-12-09 00:57:233170 // The password prompt info should not be set.
3171 EXPECT_FALSE(response->auth_challenge);
3172
3173 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3174 TestLoadTimingNotReusedWithPac(load_timing_info,
3175 CONNECT_TIMING_HAS_SSL_TIMES);
3176
3177 trans.reset();
[email protected]102e27c2011-02-23 01:01:313178 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323179}
3180
mmenkee71e15332015-10-07 16:39:543181// Test the case a proxy closes a socket while the challenge body is being
3182// drained.
3183TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
3184 HttpRequestInfo request;
3185 request.method = "GET";
3186 request.url = GURL("https://www.example.org/");
3187 // Ensure that proxy authentication is attempted even
3188 // when the no authentication data flag is set.
3189 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3190
3191 // Configure against proxy server "myproxy:70".
3192 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093193 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543194
danakj1fd259a02016-04-16 03:17:093195 std::unique_ptr<HttpTransaction> trans(
mmenkee71e15332015-10-07 16:39:543196 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3197
3198 // Since we have proxy, should try to establish tunnel.
3199 MockWrite data_writes1[] = {
3200 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173201 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543202 "Proxy-Connection: keep-alive\r\n\r\n"),
3203 };
3204
3205 // The proxy responds to the connect with a 407, using a persistent
3206 // connection.
3207 MockRead data_reads1[] = {
3208 // No credentials.
3209 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3210 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3211 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3212 // Server hands up in the middle of the body.
3213 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3214 };
3215
3216 MockWrite data_writes2[] = {
3217 // After calling trans->RestartWithAuth(), this is the request we should
3218 // be issuing -- the final header line contains the credentials.
3219 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173220 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543221 "Proxy-Connection: keep-alive\r\n"
3222 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3223
3224 MockWrite("GET / HTTP/1.1\r\n"
3225 "Host: www.example.org\r\n"
3226 "Connection: keep-alive\r\n\r\n"),
3227 };
3228
3229 MockRead data_reads2[] = {
3230 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3231
3232 MockRead("HTTP/1.1 200 OK\r\n"),
3233 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3234 MockRead("Content-Length: 5\r\n\r\n"),
3235 MockRead(SYNCHRONOUS, "hello"),
3236 };
3237
3238 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3239 data_writes1, arraysize(data_writes1));
3240 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3241 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3242 data_writes2, arraysize(data_writes2));
3243 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3244 SSLSocketDataProvider ssl(ASYNC, OK);
3245 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3246
3247 TestCompletionCallback callback;
3248
3249 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3250 EXPECT_EQ(OK, callback.GetResult(rv));
3251
3252 const HttpResponseInfo* response = trans->GetResponseInfo();
3253 ASSERT_TRUE(response);
3254 ASSERT_TRUE(response->headers);
3255 EXPECT_TRUE(response->headers->IsKeepAlive());
3256 EXPECT_EQ(407, response->headers->response_code());
3257 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3258
3259 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
3260 EXPECT_EQ(OK, callback.GetResult(rv));
3261
3262 response = trans->GetResponseInfo();
3263 ASSERT_TRUE(response);
3264 ASSERT_TRUE(response->headers);
3265 EXPECT_TRUE(response->headers->IsKeepAlive());
3266 EXPECT_EQ(200, response->headers->response_code());
3267 std::string body;
3268 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
3269 EXPECT_EQ("hello", body);
3270}
3271
[email protected]a8e9b162009-03-12 00:06:443272// Test that we don't read the response body when we fail to establish a tunnel,
3273// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:023274TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273275 HttpRequestInfo request;
3276 request.method = "GET";
bncce36dca22015-04-21 22:11:233277 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273278 request.load_flags = 0;
3279
[email protected]a8e9b162009-03-12 00:06:443280 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033281 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443282
danakj1fd259a02016-04-16 03:17:093283 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443284
danakj1fd259a02016-04-16 03:17:093285 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503286 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:443287
[email protected]a8e9b162009-03-12 00:06:443288 // Since we have proxy, should try to establish tunnel.
3289 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173290 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3291 "Host: www.example.org:443\r\n"
3292 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443293 };
3294
3295 // The proxy responds to the connect with a 407.
3296 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243297 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3298 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3299 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233300 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243301 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443302 };
3303
[email protected]31a2bfe2010-02-09 08:03:393304 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3305 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073306 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443307
[email protected]49639fa2011-12-20 23:22:413308 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443309
[email protected]49639fa2011-12-20 23:22:413310 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423311 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:443312
3313 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423314 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:443315
[email protected]1c773ea12009-04-28 19:58:423316 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243317 ASSERT_TRUE(response);
3318 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443319 EXPECT_TRUE(response->headers->IsKeepAlive());
3320 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423321 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443322
3323 std::string response_data;
3324 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423325 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:183326
3327 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313328 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443329}
3330
ttuttle7933c112015-01-06 00:55:243331// Test that we don't pass extraneous headers from the proxy's response to the
3332// caller when the proxy responds to CONNECT with 407.
3333TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3334 HttpRequestInfo request;
3335 request.method = "GET";
bncce36dca22015-04-21 22:11:233336 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243337 request.load_flags = 0;
3338
3339 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033340 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243341
danakj1fd259a02016-04-16 03:17:093342 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243343
danakj1fd259a02016-04-16 03:17:093344 std::unique_ptr<HttpTransaction> trans(
ttuttle7933c112015-01-06 00:55:243345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3346
3347 // Since we have proxy, should try to establish tunnel.
3348 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173349 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3350 "Host: www.example.org:443\r\n"
3351 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243352 };
3353
3354 // The proxy responds to the connect with a 407.
3355 MockRead data_reads[] = {
3356 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3357 MockRead("X-Foo: bar\r\n"),
3358 MockRead("Set-Cookie: foo=bar\r\n"),
3359 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3360 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233361 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243362 };
3363
3364 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3365 arraysize(data_writes));
3366 session_deps_.socket_factory->AddSocketDataProvider(&data);
3367
3368 TestCompletionCallback callback;
3369
3370 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3371 EXPECT_EQ(ERR_IO_PENDING, rv);
3372
3373 rv = callback.WaitForResult();
3374 EXPECT_EQ(OK, rv);
3375
3376 const HttpResponseInfo* response = trans->GetResponseInfo();
3377 ASSERT_TRUE(response);
3378 ASSERT_TRUE(response->headers);
3379 EXPECT_TRUE(response->headers->IsKeepAlive());
3380 EXPECT_EQ(407, response->headers->response_code());
3381 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3382 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3383 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3384
3385 std::string response_data;
3386 rv = ReadTransaction(trans.get(), &response_data);
3387 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3388
3389 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3390 session->CloseAllConnections();
3391}
3392
[email protected]8fdbcd22010-05-05 02:54:523393// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3394// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023395TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523396 HttpRequestInfo request;
3397 request.method = "GET";
bncce36dca22015-04-21 22:11:233398 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523399 request.load_flags = 0;
3400
[email protected]cb9bf6ca2011-01-28 13:15:273401 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093402 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3403 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413404 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273405
[email protected]8fdbcd22010-05-05 02:54:523406 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233407 MockWrite(
3408 "GET / HTTP/1.1\r\n"
3409 "Host: www.example.org\r\n"
3410 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523411 };
3412
3413 MockRead data_reads1[] = {
3414 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3415 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3416 // Large content-length -- won't matter, as connection will be reset.
3417 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063418 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523419 };
3420
3421 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3422 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073423 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523424
[email protected]49639fa2011-12-20 23:22:413425 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523426
[email protected]49639fa2011-12-20 23:22:413427 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523428 EXPECT_EQ(ERR_IO_PENDING, rv);
3429
3430 rv = callback.WaitForResult();
3431 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3432}
3433
[email protected]7a67a8152010-11-05 18:31:103434// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3435// through a non-authenticating proxy. The request should fail with
3436// ERR_UNEXPECTED_PROXY_AUTH.
3437// Note that it is impossible to detect if an HTTP server returns a 407 through
3438// a non-authenticating proxy - there is nothing to indicate whether the
3439// response came from the proxy or the server, so it is treated as if the proxy
3440// issued the challenge.
[email protected]23e482282013-06-14 16:08:023441TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233442 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273443 HttpRequestInfo request;
3444 request.method = "GET";
bncce36dca22015-04-21 22:11:233445 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273446
rdsmith82957ad2015-09-16 19:42:033447 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513448 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073449 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103451
[email protected]7a67a8152010-11-05 18:31:103452 // Since we have proxy, should try to establish tunnel.
3453 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173454 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3455 "Host: www.example.org:443\r\n"
3456 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103457
rsleevidb16bb02015-11-12 23:47:173458 MockWrite("GET / HTTP/1.1\r\n"
3459 "Host: www.example.org\r\n"
3460 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103461 };
3462
3463 MockRead data_reads1[] = {
3464 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3465
3466 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3467 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3468 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063469 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103470 };
3471
3472 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3473 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073474 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063475 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103477
[email protected]49639fa2011-12-20 23:22:413478 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103479
danakj1fd259a02016-04-16 03:17:093480 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503481 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103482
[email protected]49639fa2011-12-20 23:22:413483 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103484 EXPECT_EQ(ERR_IO_PENDING, rv);
3485
3486 rv = callback1.WaitForResult();
3487 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463488 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403489 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103490 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403491 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103492 NetLog::PHASE_NONE);
3493 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403494 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103495 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3496 NetLog::PHASE_NONE);
3497}
[email protected]2df19bb2010-08-25 20:13:463498
mmenke2a1781d2015-10-07 19:25:333499// Test a proxy auth scheme that allows default credentials and a proxy server
3500// that uses non-persistent connections.
3501TEST_P(HttpNetworkTransactionTest,
3502 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3503 HttpRequestInfo request;
3504 request.method = "GET";
3505 request.url = GURL("https://www.example.org/");
3506
3507 // Configure against proxy server "myproxy:70".
3508 session_deps_.proxy_service =
3509 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3510
danakj1fd259a02016-04-16 03:17:093511 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333512 new HttpAuthHandlerMock::Factory());
3513 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093514 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333515 mock_handler->set_allows_default_credentials(true);
3516 auth_handler_factory->AddMockHandler(mock_handler.release(),
3517 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483518 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333519
3520 // Add NetLog just so can verify load timing information gets a NetLog ID.
3521 NetLog net_log;
3522 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093523 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333524
3525 // Since we have proxy, should try to establish tunnel.
3526 MockWrite data_writes1[] = {
3527 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173528 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333529 "Proxy-Connection: keep-alive\r\n\r\n"),
3530 };
3531
3532 // The proxy responds to the connect with a 407, using a non-persistent
3533 // connection.
3534 MockRead data_reads1[] = {
3535 // No credentials.
3536 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3537 MockRead("Proxy-Authenticate: Mock\r\n"),
3538 MockRead("Proxy-Connection: close\r\n\r\n"),
3539 };
3540
3541 // Since the first connection couldn't be reused, need to establish another
3542 // once given credentials.
3543 MockWrite data_writes2[] = {
3544 // After calling trans->RestartWithAuth(), this is the request we should
3545 // be issuing -- the final header line contains the credentials.
3546 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173547 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333548 "Proxy-Connection: keep-alive\r\n"
3549 "Proxy-Authorization: auth_token\r\n\r\n"),
3550
3551 MockWrite("GET / HTTP/1.1\r\n"
3552 "Host: www.example.org\r\n"
3553 "Connection: keep-alive\r\n\r\n"),
3554 };
3555
3556 MockRead data_reads2[] = {
3557 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3558
3559 MockRead("HTTP/1.1 200 OK\r\n"),
3560 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3561 MockRead("Content-Length: 5\r\n\r\n"),
3562 MockRead(SYNCHRONOUS, "hello"),
3563 };
3564
3565 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3566 data_writes1, arraysize(data_writes1));
3567 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3568 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3569 data_writes2, arraysize(data_writes2));
3570 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3571 SSLSocketDataProvider ssl(ASYNC, OK);
3572 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3573
danakj1fd259a02016-04-16 03:17:093574 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333575 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3576
3577 TestCompletionCallback callback;
3578 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3579 EXPECT_EQ(OK, callback.GetResult(rv));
3580
3581 const HttpResponseInfo* response = trans->GetResponseInfo();
3582 ASSERT_TRUE(response);
3583 ASSERT_TRUE(response->headers);
3584 EXPECT_FALSE(response->headers->IsKeepAlive());
3585 EXPECT_EQ(407, response->headers->response_code());
3586 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3587 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523588 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333589
3590 LoadTimingInfo load_timing_info;
3591 // CONNECT requests and responses are handled at the connect job level, so
3592 // the transaction does not yet have a connection.
3593 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3594
3595 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3596 EXPECT_EQ(OK, callback.GetResult(rv));
3597 response = trans->GetResponseInfo();
3598 ASSERT_TRUE(response);
3599 ASSERT_TRUE(response->headers);
3600 EXPECT_TRUE(response->headers->IsKeepAlive());
3601 EXPECT_EQ(200, response->headers->response_code());
3602 EXPECT_EQ(5, response->headers->GetContentLength());
3603 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3604
3605 // The password prompt info should not be set.
3606 EXPECT_FALSE(response->auth_challenge);
3607
3608 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3609 TestLoadTimingNotReusedWithPac(load_timing_info,
3610 CONNECT_TIMING_HAS_SSL_TIMES);
3611
3612 trans.reset();
3613 session->CloseAllConnections();
3614}
3615
3616// Test a proxy auth scheme that allows default credentials and a proxy server
3617// that hangs up when credentials are initially sent.
3618TEST_P(HttpNetworkTransactionTest,
3619 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3620 HttpRequestInfo request;
3621 request.method = "GET";
3622 request.url = GURL("https://www.example.org/");
3623
3624 // Configure against proxy server "myproxy:70".
3625 session_deps_.proxy_service =
3626 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3627
danakj1fd259a02016-04-16 03:17:093628 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333629 new HttpAuthHandlerMock::Factory());
3630 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093631 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333632 mock_handler->set_allows_default_credentials(true);
3633 auth_handler_factory->AddMockHandler(mock_handler.release(),
3634 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483635 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333636
3637 // Add NetLog just so can verify load timing information gets a NetLog ID.
3638 NetLog net_log;
3639 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093640 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333641
3642 // Should try to establish tunnel.
3643 MockWrite data_writes1[] = {
3644 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173645 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333646 "Proxy-Connection: keep-alive\r\n\r\n"),
3647
3648 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173649 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333650 "Proxy-Connection: keep-alive\r\n"
3651 "Proxy-Authorization: auth_token\r\n\r\n"),
3652 };
3653
3654 // The proxy responds to the connect with a 407, using a non-persistent
3655 // connection.
3656 MockRead data_reads1[] = {
3657 // No credentials.
3658 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3659 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3660 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3661 };
3662
3663 // Since the first connection was closed, need to establish another once given
3664 // credentials.
3665 MockWrite data_writes2[] = {
3666 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173667 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333668 "Proxy-Connection: keep-alive\r\n"
3669 "Proxy-Authorization: auth_token\r\n\r\n"),
3670
3671 MockWrite("GET / HTTP/1.1\r\n"
3672 "Host: www.example.org\r\n"
3673 "Connection: keep-alive\r\n\r\n"),
3674 };
3675
3676 MockRead data_reads2[] = {
3677 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3678
3679 MockRead("HTTP/1.1 200 OK\r\n"),
3680 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3681 MockRead("Content-Length: 5\r\n\r\n"),
3682 MockRead(SYNCHRONOUS, "hello"),
3683 };
3684
3685 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3686 data_writes1, arraysize(data_writes1));
3687 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3688 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3689 data_writes2, arraysize(data_writes2));
3690 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3691 SSLSocketDataProvider ssl(ASYNC, OK);
3692 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3693
danakj1fd259a02016-04-16 03:17:093694 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3696
3697 TestCompletionCallback callback;
3698 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3699 EXPECT_EQ(OK, callback.GetResult(rv));
3700
3701 const HttpResponseInfo* response = trans->GetResponseInfo();
3702 ASSERT_TRUE(response);
3703 ASSERT_TRUE(response->headers);
3704 EXPECT_TRUE(response->headers->IsKeepAlive());
3705 EXPECT_EQ(407, response->headers->response_code());
3706 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3707 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3708 EXPECT_FALSE(response->auth_challenge);
3709
3710 LoadTimingInfo load_timing_info;
3711 // CONNECT requests and responses are handled at the connect job level, so
3712 // the transaction does not yet have a connection.
3713 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3714
3715 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3716 EXPECT_EQ(OK, callback.GetResult(rv));
3717
3718 response = trans->GetResponseInfo();
3719 ASSERT_TRUE(response);
3720 ASSERT_TRUE(response->headers);
3721 EXPECT_TRUE(response->headers->IsKeepAlive());
3722 EXPECT_EQ(200, response->headers->response_code());
3723 EXPECT_EQ(5, response->headers->GetContentLength());
3724 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3725
3726 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523727 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333728
3729 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3730 TestLoadTimingNotReusedWithPac(load_timing_info,
3731 CONNECT_TIMING_HAS_SSL_TIMES);
3732
3733 trans.reset();
3734 session->CloseAllConnections();
3735}
3736
3737// Test a proxy auth scheme that allows default credentials and a proxy server
3738// that hangs up when credentials are initially sent, and hangs up again when
3739// they are retried.
3740TEST_P(HttpNetworkTransactionTest,
3741 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
3742 HttpRequestInfo request;
3743 request.method = "GET";
3744 request.url = GURL("https://www.example.org/");
3745
3746 // Configure against proxy server "myproxy:70".
3747 session_deps_.proxy_service =
3748 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3749
danakj1fd259a02016-04-16 03:17:093750 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333751 new HttpAuthHandlerMock::Factory());
3752 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093753 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333754 mock_handler->set_allows_default_credentials(true);
3755 auth_handler_factory->AddMockHandler(mock_handler.release(),
3756 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483757 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333758
3759 // Add NetLog just so can verify load timing information gets a NetLog ID.
3760 NetLog net_log;
3761 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093762 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333763
3764 // Should try to establish tunnel.
3765 MockWrite data_writes1[] = {
3766 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173767 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333768 "Proxy-Connection: keep-alive\r\n\r\n"),
3769
3770 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173771 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333772 "Proxy-Connection: keep-alive\r\n"
3773 "Proxy-Authorization: auth_token\r\n\r\n"),
3774 };
3775
3776 // The proxy responds to the connect with a 407, and then hangs up after the
3777 // second request is sent.
3778 MockRead data_reads1[] = {
3779 // No credentials.
3780 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3781 MockRead("Content-Length: 0\r\n"),
3782 MockRead("Proxy-Connection: keep-alive\r\n"),
3783 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3784 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3785 };
3786
3787 // HttpNetworkTransaction sees a reused connection that was closed with
3788 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
3789 // request.
3790 MockWrite data_writes2[] = {
3791 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173792 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333793 "Proxy-Connection: keep-alive\r\n\r\n"),
3794 };
3795
3796 // The proxy, having had more than enough of us, just hangs up.
3797 MockRead data_reads2[] = {
3798 // No credentials.
3799 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3800 };
3801
3802 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3803 data_writes1, arraysize(data_writes1));
3804 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3805 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3806 data_writes2, arraysize(data_writes2));
3807 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3808
danakj1fd259a02016-04-16 03:17:093809 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333810 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3811
3812 TestCompletionCallback callback;
3813 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3814 EXPECT_EQ(OK, callback.GetResult(rv));
3815
3816 const HttpResponseInfo* response = trans->GetResponseInfo();
3817 ASSERT_TRUE(response);
3818 ASSERT_TRUE(response->headers);
3819 EXPECT_TRUE(response->headers->IsKeepAlive());
3820 EXPECT_EQ(407, response->headers->response_code());
3821 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3822 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3823 EXPECT_FALSE(response->auth_challenge);
3824
3825 LoadTimingInfo load_timing_info;
3826 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3827
3828 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3829 EXPECT_EQ(ERR_EMPTY_RESPONSE, callback.GetResult(rv));
3830
3831 trans.reset();
3832 session->CloseAllConnections();
3833}
3834
3835// Test a proxy auth scheme that allows default credentials and a proxy server
3836// that hangs up when credentials are initially sent, and sends a challenge
3837// again they are retried.
3838TEST_P(HttpNetworkTransactionTest,
3839 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
3840 HttpRequestInfo request;
3841 request.method = "GET";
3842 request.url = GURL("https://www.example.org/");
3843
3844 // Configure against proxy server "myproxy:70".
3845 session_deps_.proxy_service =
3846 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3847
danakj1fd259a02016-04-16 03:17:093848 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333849 new HttpAuthHandlerMock::Factory());
3850 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093851 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333852 mock_handler->set_allows_default_credentials(true);
3853 auth_handler_factory->AddMockHandler(mock_handler.release(),
3854 HttpAuth::AUTH_PROXY);
3855 // Add another handler for the second challenge. It supports default
3856 // credentials, but they shouldn't be used, since they were already tried.
3857 mock_handler.reset(new HttpAuthHandlerMock());
3858 mock_handler->set_allows_default_credentials(true);
3859 auth_handler_factory->AddMockHandler(mock_handler.release(),
3860 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483861 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333862
3863 // Add NetLog just so can verify load timing information gets a NetLog ID.
3864 NetLog net_log;
3865 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093866 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333867
3868 // Should try to establish tunnel.
3869 MockWrite data_writes1[] = {
3870 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173871 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333872 "Proxy-Connection: keep-alive\r\n\r\n"),
3873 };
3874
3875 // The proxy responds to the connect with a 407, using a non-persistent
3876 // connection.
3877 MockRead data_reads1[] = {
3878 // No credentials.
3879 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3880 MockRead("Proxy-Authenticate: Mock\r\n"),
3881 MockRead("Proxy-Connection: close\r\n\r\n"),
3882 };
3883
3884 // Since the first connection was closed, need to establish another once given
3885 // credentials.
3886 MockWrite data_writes2[] = {
3887 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173888 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333889 "Proxy-Connection: keep-alive\r\n"
3890 "Proxy-Authorization: auth_token\r\n\r\n"),
3891 };
3892
3893 MockRead data_reads2[] = {
3894 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3895 MockRead("Proxy-Authenticate: Mock\r\n"),
3896 MockRead("Proxy-Connection: close\r\n\r\n"),
3897 };
3898
3899 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3900 data_writes1, arraysize(data_writes1));
3901 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3902 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3903 data_writes2, arraysize(data_writes2));
3904 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3905 SSLSocketDataProvider ssl(ASYNC, OK);
3906 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3907
danakj1fd259a02016-04-16 03:17:093908 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333909 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3910
3911 TestCompletionCallback callback;
3912 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3913 EXPECT_EQ(OK, callback.GetResult(rv));
3914
3915 const HttpResponseInfo* response = trans->GetResponseInfo();
3916 ASSERT_TRUE(response);
3917 ASSERT_TRUE(response->headers);
3918 EXPECT_EQ(407, response->headers->response_code());
3919 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3920 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3921 EXPECT_FALSE(response->auth_challenge);
3922
3923 LoadTimingInfo load_timing_info;
3924 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3925
3926 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3927 EXPECT_EQ(OK, callback.GetResult(rv));
3928 response = trans->GetResponseInfo();
3929 ASSERT_TRUE(response);
3930 ASSERT_TRUE(response->headers);
3931 EXPECT_EQ(407, response->headers->response_code());
3932 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3933 EXPECT_TRUE(response->auth_challenge);
3934
3935 trans.reset();
3936 session->CloseAllConnections();
3937}
3938
[email protected]029c83b62013-01-24 05:28:203939// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023940TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203941 HttpRequestInfo request1;
3942 request1.method = "GET";
bncce36dca22015-04-21 22:11:233943 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203944
3945 HttpRequestInfo request2;
3946 request2.method = "GET";
bncce36dca22015-04-21 22:11:233947 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203948
3949 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033950 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513951 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073952 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093953 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203954
3955 // Since we have proxy, should try to establish tunnel.
3956 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173957 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3958 "Host: www.example.org:443\r\n"
3959 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203960
rsleevidb16bb02015-11-12 23:47:173961 MockWrite("GET /1 HTTP/1.1\r\n"
3962 "Host: www.example.org\r\n"
3963 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203964
rsleevidb16bb02015-11-12 23:47:173965 MockWrite("GET /2 HTTP/1.1\r\n"
3966 "Host: www.example.org\r\n"
3967 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203968 };
3969
3970 // The proxy responds to the connect with a 407, using a persistent
3971 // connection.
3972 MockRead data_reads1[] = {
3973 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3974
3975 MockRead("HTTP/1.1 200 OK\r\n"),
3976 MockRead("Content-Length: 1\r\n\r\n"),
3977 MockRead(SYNCHRONOUS, "1"),
3978
3979 MockRead("HTTP/1.1 200 OK\r\n"),
3980 MockRead("Content-Length: 2\r\n\r\n"),
3981 MockRead(SYNCHRONOUS, "22"),
3982 };
3983
3984 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3985 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073986 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203987 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073988 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203989
3990 TestCompletionCallback callback1;
danakj1fd259a02016-04-16 03:17:093991 std::unique_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503992 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203993
3994 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3995 EXPECT_EQ(ERR_IO_PENDING, rv);
3996
3997 rv = callback1.WaitForResult();
3998 EXPECT_EQ(OK, rv);
3999
4000 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524001 ASSERT_TRUE(response1);
4002 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204003 EXPECT_EQ(1, response1->headers->GetContentLength());
4004
4005 LoadTimingInfo load_timing_info1;
4006 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4007 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4008
4009 trans1.reset();
4010
4011 TestCompletionCallback callback2;
danakj1fd259a02016-04-16 03:17:094012 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504013 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204014
4015 rv = trans2->Start(&request2, callback2.callback(), log.bound());
4016 EXPECT_EQ(ERR_IO_PENDING, rv);
4017
4018 rv = callback2.WaitForResult();
4019 EXPECT_EQ(OK, rv);
4020
4021 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524022 ASSERT_TRUE(response2);
4023 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204024 EXPECT_EQ(2, response2->headers->GetContentLength());
4025
4026 LoadTimingInfo load_timing_info2;
4027 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4028 TestLoadTimingReused(load_timing_info2);
4029
4030 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4031
4032 trans2.reset();
4033 session->CloseAllConnections();
4034}
4035
4036// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:024037TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204038 HttpRequestInfo request1;
4039 request1.method = "GET";
bncce36dca22015-04-21 22:11:234040 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204041
4042 HttpRequestInfo request2;
4043 request2.method = "GET";
bncce36dca22015-04-21 22:11:234044 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204045
4046 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034047 session_deps_.proxy_service =
4048 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514049 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074050 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094051 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204052
4053 // Since we have proxy, should try to establish tunnel.
4054 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174055 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4056 "Host: www.example.org:443\r\n"
4057 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204058
rsleevidb16bb02015-11-12 23:47:174059 MockWrite("GET /1 HTTP/1.1\r\n"
4060 "Host: www.example.org\r\n"
4061 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204062
rsleevidb16bb02015-11-12 23:47:174063 MockWrite("GET /2 HTTP/1.1\r\n"
4064 "Host: www.example.org\r\n"
4065 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204066 };
4067
4068 // The proxy responds to the connect with a 407, using a persistent
4069 // connection.
4070 MockRead data_reads1[] = {
4071 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4072
4073 MockRead("HTTP/1.1 200 OK\r\n"),
4074 MockRead("Content-Length: 1\r\n\r\n"),
4075 MockRead(SYNCHRONOUS, "1"),
4076
4077 MockRead("HTTP/1.1 200 OK\r\n"),
4078 MockRead("Content-Length: 2\r\n\r\n"),
4079 MockRead(SYNCHRONOUS, "22"),
4080 };
4081
4082 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4083 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074084 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204085 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204087
4088 TestCompletionCallback callback1;
danakj1fd259a02016-04-16 03:17:094089 std::unique_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:504090 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204091
4092 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
4093 EXPECT_EQ(ERR_IO_PENDING, rv);
4094
4095 rv = callback1.WaitForResult();
4096 EXPECT_EQ(OK, rv);
4097
4098 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524099 ASSERT_TRUE(response1);
4100 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204101 EXPECT_EQ(1, response1->headers->GetContentLength());
4102
4103 LoadTimingInfo load_timing_info1;
4104 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4105 TestLoadTimingNotReusedWithPac(load_timing_info1,
4106 CONNECT_TIMING_HAS_SSL_TIMES);
4107
4108 trans1.reset();
4109
4110 TestCompletionCallback callback2;
danakj1fd259a02016-04-16 03:17:094111 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504112 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204113
4114 rv = trans2->Start(&request2, callback2.callback(), log.bound());
4115 EXPECT_EQ(ERR_IO_PENDING, rv);
4116
4117 rv = callback2.WaitForResult();
4118 EXPECT_EQ(OK, rv);
4119
4120 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524121 ASSERT_TRUE(response2);
4122 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204123 EXPECT_EQ(2, response2->headers->GetContentLength());
4124
4125 LoadTimingInfo load_timing_info2;
4126 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4127 TestLoadTimingReusedWithPac(load_timing_info2);
4128
4129 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4130
4131 trans2.reset();
4132 session->CloseAllConnections();
4133}
4134
[email protected]2df19bb2010-08-25 20:13:464135// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024136TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274137 HttpRequestInfo request;
4138 request.method = "GET";
bncce36dca22015-04-21 22:11:234139 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274140
[email protected]2df19bb2010-08-25 20:13:464141 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034142 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514143 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074144 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094145 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464146
[email protected]2df19bb2010-08-25 20:13:464147 // Since we have proxy, should use full url
4148 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234149 MockWrite(
4150 "GET http://www.example.org/ HTTP/1.1\r\n"
4151 "Host: www.example.org\r\n"
4152 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464153 };
4154
4155 MockRead data_reads1[] = {
4156 MockRead("HTTP/1.1 200 OK\r\n"),
4157 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4158 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064159 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464160 };
4161
4162 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4163 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074164 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064165 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074166 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464167
[email protected]49639fa2011-12-20 23:22:414168 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464169
danakj1fd259a02016-04-16 03:17:094170 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504172
[email protected]49639fa2011-12-20 23:22:414173 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464174 EXPECT_EQ(ERR_IO_PENDING, rv);
4175
4176 rv = callback1.WaitForResult();
4177 EXPECT_EQ(OK, rv);
4178
[email protected]58e32bb2013-01-21 18:23:254179 LoadTimingInfo load_timing_info;
4180 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4181 TestLoadTimingNotReused(load_timing_info,
4182 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4183
[email protected]2df19bb2010-08-25 20:13:464184 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524185 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464186
4187 EXPECT_TRUE(response->headers->IsKeepAlive());
4188 EXPECT_EQ(200, response->headers->response_code());
4189 EXPECT_EQ(100, response->headers->GetContentLength());
4190 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4191
4192 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524193 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464194}
4195
[email protected]7642b5ae2010-09-01 20:55:174196// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024197TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274198 HttpRequestInfo request;
4199 request.method = "GET";
bncce36dca22015-04-21 22:11:234200 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274201 request.load_flags = 0;
4202
[email protected]7642b5ae2010-09-01 20:55:174203 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034204 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514205 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074206 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094207 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174208
bncce36dca22015-04-21 22:11:234209 // fetch http://www.example.org/ via SPDY
danakj1fd259a02016-04-16 03:17:094210 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:494211 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134212 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174213
danakj1fd259a02016-04-16 03:17:094214 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554215 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:094216 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554217 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174218 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134219 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174220 };
4221
rch8e6c6c42015-05-01 14:05:134222 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4223 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074224 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174225
[email protected]8ddf8322012-02-23 18:08:064226 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384227 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074228 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174229
[email protected]49639fa2011-12-20 23:22:414230 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174231
danakj1fd259a02016-04-16 03:17:094232 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504233 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504234
[email protected]49639fa2011-12-20 23:22:414235 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:174236 EXPECT_EQ(ERR_IO_PENDING, rv);
4237
4238 rv = callback1.WaitForResult();
4239 EXPECT_EQ(OK, rv);
4240
[email protected]58e32bb2013-01-21 18:23:254241 LoadTimingInfo load_timing_info;
4242 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4243 TestLoadTimingNotReused(load_timing_info,
4244 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4245
[email protected]7642b5ae2010-09-01 20:55:174246 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524247 ASSERT_TRUE(response);
4248 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024249 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174250
4251 std::string response_data;
4252 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234253 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174254}
4255
[email protected]1c173852014-06-19 12:51:504256// Verifies that a session which races and wins against the owning transaction
4257// (completing prior to host resolution), doesn't fail the transaction.
4258// Regression test for crbug.com/334413.
4259TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
4260 HttpRequestInfo request;
4261 request.method = "GET";
bncce36dca22015-04-21 22:11:234262 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504263 request.load_flags = 0;
4264
4265 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034266 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514267 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504268 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094269 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504270
bncce36dca22015-04-21 22:11:234271 // Fetch http://www.example.org/ through the SPDY proxy.
danakj1fd259a02016-04-16 03:17:094272 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:494273 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134274 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:504275
danakj1fd259a02016-04-16 03:17:094276 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554277 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094278 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554279 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]1c173852014-06-19 12:51:504280 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134281 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504282 };
4283
rch8e6c6c42015-05-01 14:05:134284 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4285 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504286 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4287
4288 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384289 ssl.SetNextProto(GetProtocol());
[email protected]1c173852014-06-19 12:51:504290 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4291
4292 TestCompletionCallback callback1;
4293
danakj1fd259a02016-04-16 03:17:094294 std::unique_ptr<HttpTransaction> trans(
[email protected]1c173852014-06-19 12:51:504295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4296
4297 // Stall the hostname resolution begun by the transaction.
4298 session_deps_.host_resolver->set_synchronous_mode(false);
4299 session_deps_.host_resolver->set_ondemand_mode(true);
4300
4301 int rv = trans->Start(&request, callback1.callback(), log.bound());
4302 EXPECT_EQ(ERR_IO_PENDING, rv);
4303
4304 // Race a session to the proxy, which completes first.
4305 session_deps_.host_resolver->set_ondemand_mode(false);
4306 SpdySessionKey key(
4307 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4308 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424309 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504310
4311 // Unstall the resolution begun by the transaction.
4312 session_deps_.host_resolver->set_ondemand_mode(true);
4313 session_deps_.host_resolver->ResolveAllPending();
4314
4315 EXPECT_FALSE(callback1.have_result());
4316 rv = callback1.WaitForResult();
4317 EXPECT_EQ(OK, rv);
4318
4319 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524320 ASSERT_TRUE(response);
4321 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024322 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504323
4324 std::string response_data;
4325 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4326 EXPECT_EQ(kUploadData, response_data);
4327}
4328
[email protected]dc7bd1c52010-11-12 00:01:134329// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024330TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274331 HttpRequestInfo request;
4332 request.method = "GET";
bncce36dca22015-04-21 22:11:234333 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274334 request.load_flags = 0;
4335
[email protected]79cb5c12011-09-12 13:12:044336 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034337 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514338 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074339 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094340 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134341
[email protected]dc7bd1c52010-11-12 00:01:134342 // The first request will be a bare GET, the second request will be a
4343 // GET with a Proxy-Authorization header.
danakj1fd259a02016-04-16 03:17:094344 std::unique_ptr<SpdySerializedFrame> req_get(
bnc38dcd392016-02-09 23:19:494345 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384346 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134347 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464348 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134349 };
danakj1fd259a02016-04-16 03:17:094350 std::unique_ptr<SpdySerializedFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:464351 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
bncb03b1092016-04-06 11:19:554352 arraysize(kExtraAuthorizationHeaders) / 2, 3,
4353 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134354 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134355 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134356 };
4357
4358 // The first response is a 407 proxy authentication challenge, and the second
4359 // response will be a 200 response since the second request includes a valid
4360 // Authorization header.
4361 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464362 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134363 };
danakj1fd259a02016-04-16 03:17:094364 std::unique_ptr<SpdySerializedFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:024365 spdy_util_.ConstructSpdySynReplyError(
bncb03b1092016-04-06 11:19:554366 "407 Proxy Authentication Required", kExtraAuthenticationHeaders,
4367 arraysize(kExtraAuthenticationHeaders) / 2, 1));
danakj1fd259a02016-04-16 03:17:094368 std::unique_ptr<SpdySerializedFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:024369 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:094370 std::unique_ptr<SpdySerializedFrame> resp_data(
[email protected]23e482282013-06-14 16:08:024371 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:094372 std::unique_ptr<SpdySerializedFrame> body_data(
bncb03b1092016-04-06 11:19:554373 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134374 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134375 CreateMockRead(*resp_authentication, 1),
4376 CreateMockRead(*body_authentication, 2),
4377 CreateMockRead(*resp_data, 4),
4378 CreateMockRead(*body_data, 5),
4379 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134380 };
4381
rch8e6c6c42015-05-01 14:05:134382 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4383 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074384 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134385
[email protected]8ddf8322012-02-23 18:08:064386 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384387 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074388 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134389
[email protected]49639fa2011-12-20 23:22:414390 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134391
danakj1fd259a02016-04-16 03:17:094392 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504393 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:134394
[email protected]49639fa2011-12-20 23:22:414395 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:134396 EXPECT_EQ(ERR_IO_PENDING, rv);
4397
4398 rv = callback1.WaitForResult();
4399 EXPECT_EQ(OK, rv);
4400
4401 const HttpResponseInfo* const response = trans->GetResponseInfo();
4402
wezca1070932016-05-26 20:30:524403 ASSERT_TRUE(response);
4404 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134405 EXPECT_EQ(407, response->headers->response_code());
4406 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:044407 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134408
[email protected]49639fa2011-12-20 23:22:414409 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134410
[email protected]49639fa2011-12-20 23:22:414411 rv = trans->RestartWithAuth(
4412 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:134413 EXPECT_EQ(ERR_IO_PENDING, rv);
4414
4415 rv = callback2.WaitForResult();
4416 EXPECT_EQ(OK, rv);
4417
4418 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
4419
wezca1070932016-05-26 20:30:524420 ASSERT_TRUE(response_restart);
4421 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134422 EXPECT_EQ(200, response_restart->headers->response_code());
4423 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524424 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134425}
4426
[email protected]d9da5fe2010-10-13 22:37:164427// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:024428TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274429 HttpRequestInfo request;
4430 request.method = "GET";
bncce36dca22015-04-21 22:11:234431 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274432 request.load_flags = 0;
4433
[email protected]d9da5fe2010-10-13 22:37:164434 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034435 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514436 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074437 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094438 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164439
danakj1fd259a02016-04-16 03:17:094440 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504441 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164442
bncce36dca22015-04-21 22:11:234443 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094444 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234445 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4446 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164447
bncce36dca22015-04-21 22:11:234448 const char get[] =
4449 "GET / HTTP/1.1\r\n"
4450 "Host: www.example.org\r\n"
4451 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094452 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024453 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
danakj1fd259a02016-04-16 03:17:094454 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:024455 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164456 const char resp[] = "HTTP/1.1 200 OK\r\n"
4457 "Content-Length: 10\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094458 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024459 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
danakj1fd259a02016-04-16 03:17:094460 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024461 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
danakj1fd259a02016-04-16 03:17:094462 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204463 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:044464
4465 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134466 CreateMockWrite(*connect, 0),
4467 CreateMockWrite(*wrapped_get, 2),
4468 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044469 };
4470
[email protected]d9da5fe2010-10-13 22:37:164471 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134472 CreateMockRead(*conn_resp, 1, ASYNC),
4473 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
4474 CreateMockRead(*wrapped_body, 4, ASYNC),
4475 CreateMockRead(*wrapped_body, 5, ASYNC),
4476 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164477 };
4478
rch8e6c6c42015-05-01 14:05:134479 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4480 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074481 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164482
[email protected]8ddf8322012-02-23 18:08:064483 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384484 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074485 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064486 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074487 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164488
[email protected]49639fa2011-12-20 23:22:414489 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164490
[email protected]49639fa2011-12-20 23:22:414491 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164492 EXPECT_EQ(ERR_IO_PENDING, rv);
4493
4494 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:134495 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:164496
[email protected]58e32bb2013-01-21 18:23:254497 LoadTimingInfo load_timing_info;
4498 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4499 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4500
[email protected]d9da5fe2010-10-13 22:37:164501 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524502 ASSERT_TRUE(response);
4503 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164504 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4505
4506 std::string response_data;
4507 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4508 EXPECT_EQ("1234567890", response_data);
4509}
4510
4511// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:024512TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
rdsmithebb50aa2015-11-12 03:44:384513 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
4514
[email protected]cb9bf6ca2011-01-28 13:15:274515 HttpRequestInfo request;
4516 request.method = "GET";
bncce36dca22015-04-21 22:11:234517 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274518 request.load_flags = 0;
4519
[email protected]d9da5fe2010-10-13 22:37:164520 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034521 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514522 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074523 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094524 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164525
danakj1fd259a02016-04-16 03:17:094526 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504527 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164528
bncce36dca22015-04-21 22:11:234529 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094530 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234531 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4532 // fetch https://www.example.org/ via SPDY
4533 const char kMyUrl[] = "https://www.example.org/";
danakj1fd259a02016-04-16 03:17:094534 std::unique_ptr<SpdySerializedFrame> get(
bnc38dcd392016-02-09 23:19:494535 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
danakj1fd259a02016-04-16 03:17:094536 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024537 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
danakj1fd259a02016-04-16 03:17:094538 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:024539 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094540 std::unique_ptr<SpdySerializedFrame> get_resp(
rdsmithebb50aa2015-11-12 03:44:384541 spdy_util_wrapped.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094542 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024543 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
danakj1fd259a02016-04-16 03:17:094544 std::unique_ptr<SpdySerializedFrame> body(
bncb03b1092016-04-06 11:19:554545 spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:094546 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024547 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
danakj1fd259a02016-04-16 03:17:094548 std::unique_ptr<SpdySerializedFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:204549 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
danakj1fd259a02016-04-16 03:17:094550 std::unique_ptr<SpdySerializedFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:204551 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:044552
4553 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:094554 CreateMockWrite(*connect, 0),
4555 CreateMockWrite(*wrapped_get, 2),
4556 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:044557 CreateMockWrite(*window_update_body, 7),
4558 };
4559
[email protected]d9da5fe2010-10-13 22:37:164560 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:094561 CreateMockRead(*conn_resp, 1, ASYNC),
4562 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:134563 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:094564 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134565 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164566 };
4567
rch32320842015-05-16 15:57:094568 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4569 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074570 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164571
[email protected]8ddf8322012-02-23 18:08:064572 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384573 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074574 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064575 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384576 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074577 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164578
[email protected]49639fa2011-12-20 23:22:414579 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164580
[email protected]49639fa2011-12-20 23:22:414581 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164582 EXPECT_EQ(ERR_IO_PENDING, rv);
4583
rch32320842015-05-16 15:57:094584 // Allow the SpdyProxyClientSocket's write callback to complete.
4585 base::MessageLoop::current()->RunUntilIdle();
4586 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:594587 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:164588 rv = callback1.WaitForResult();
4589 EXPECT_EQ(OK, rv);
4590
[email protected]58e32bb2013-01-21 18:23:254591 LoadTimingInfo load_timing_info;
4592 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4593 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4594
[email protected]d9da5fe2010-10-13 22:37:164595 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524596 ASSERT_TRUE(response);
4597 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024598 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:164599
4600 std::string response_data;
4601 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234602 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:164603}
4604
4605// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024606TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:274607 HttpRequestInfo request;
4608 request.method = "GET";
bncce36dca22015-04-21 22:11:234609 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274610 request.load_flags = 0;
4611
[email protected]d9da5fe2010-10-13 22:37:164612 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034613 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514614 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074615 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094616 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164617
danakj1fd259a02016-04-16 03:17:094618 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504619 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164620
bncce36dca22015-04-21 22:11:234621 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094622 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234623 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:094624 std::unique_ptr<SpdySerializedFrame> get(
[email protected]c10b20852013-05-15 21:29:204625 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:164626
4627 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134628 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:164629 };
4630
danakj1fd259a02016-04-16 03:17:094631 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554632 spdy_util_.ConstructSpdySynReplyError(1));
danakj1fd259a02016-04-16 03:17:094633 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554634 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:164635 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134636 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:164637 };
4638
rch8e6c6c42015-05-01 14:05:134639 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4640 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074641 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164642
[email protected]8ddf8322012-02-23 18:08:064643 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384644 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074645 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064646 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384647 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074648 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164649
[email protected]49639fa2011-12-20 23:22:414650 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164651
[email protected]49639fa2011-12-20 23:22:414652 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164653 EXPECT_EQ(ERR_IO_PENDING, rv);
4654
4655 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:174656 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:164657
ttuttle960fcbf2016-04-19 13:26:324658 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:164659}
4660
[email protected]f6c63db52013-02-02 00:35:224661// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4662// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024663TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224664 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
4665 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034666 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514667 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074668 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094669 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504670 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224671
4672 HttpRequestInfo request1;
4673 request1.method = "GET";
bncce36dca22015-04-21 22:11:234674 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224675 request1.load_flags = 0;
4676
4677 HttpRequestInfo request2;
4678 request2.method = "GET";
bncce36dca22015-04-21 22:11:234679 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224680 request2.load_flags = 0;
4681
bncce36dca22015-04-21 22:11:234682 // CONNECT to www.example.org:443 via SPDY.
danakj1fd259a02016-04-16 03:17:094683 std::unique_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234684 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:094685 std::unique_ptr<SpdySerializedFrame> conn_resp1(
[email protected]23e482282013-06-14 16:08:024686 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224687
bncce36dca22015-04-21 22:11:234688 // Fetch https://www.example.org/ via HTTP.
4689 const char get1[] =
4690 "GET / HTTP/1.1\r\n"
4691 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224692 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094693 std::unique_ptr<SpdySerializedFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024694 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224695 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4696 "Content-Length: 1\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094697 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024698 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
danakj1fd259a02016-04-16 03:17:094699 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
[email protected]23e482282013-06-14 16:08:024700 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
danakj1fd259a02016-04-16 03:17:094701 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204702 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224703
bncce36dca22015-04-21 22:11:234704 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:294705 SpdyHeaderBlock connect2_block;
bnc7ecc1122015-09-28 13:22:494706 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]745aa9c2014-06-27 02:21:294707 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
rdsmithebb50aa2015-11-12 03:44:384708 if (GetProtocol() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:324709 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
4710 } else {
bnc6b996d532015-07-29 10:51:324711 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
bnc7ecc1122015-09-28 13:22:494712 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
bnc6b996d532015-07-29 10:51:324713 }
danakj1fd259a02016-04-16 03:17:094714 std::unique_ptr<SpdySerializedFrame> connect2(
bnc38dcd392016-02-09 23:19:494715 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false));
[email protected]601e03f12014-04-06 16:26:394716
danakj1fd259a02016-04-16 03:17:094717 std::unique_ptr<SpdySerializedFrame> conn_resp2(
[email protected]23e482282013-06-14 16:08:024718 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:224719
bncce36dca22015-04-21 22:11:234720 // Fetch https://mail.example.org/ via HTTP.
4721 const char get2[] =
4722 "GET / HTTP/1.1\r\n"
4723 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224724 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094725 std::unique_ptr<SpdySerializedFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024726 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224727 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4728 "Content-Length: 2\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094729 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024730 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
danakj1fd259a02016-04-16 03:17:094731 std::unique_ptr<SpdySerializedFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024732 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224733
4734 MockWrite spdy_writes[] = {
4735 CreateMockWrite(*connect1, 0),
4736 CreateMockWrite(*wrapped_get1, 2),
4737 CreateMockWrite(*connect2, 5),
4738 CreateMockWrite(*wrapped_get2, 7),
4739 };
4740
4741 MockRead spdy_reads[] = {
4742 CreateMockRead(*conn_resp1, 1, ASYNC),
4743 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4744 CreateMockRead(*wrapped_body1, 4, ASYNC),
4745 CreateMockRead(*conn_resp2, 6, ASYNC),
4746 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
4747 CreateMockRead(*wrapped_body2, 9, ASYNC),
4748 MockRead(ASYNC, 0, 10),
4749 };
4750
mmenke11eb5152015-06-09 14:50:504751 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4752 arraysize(spdy_writes));
4753 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224754
4755 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384756 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:504757 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224758 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224760 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504761 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:224762
4763 TestCompletionCallback callback;
4764
danakj1fd259a02016-04-16 03:17:094765 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504766 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224767 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504768 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224769
4770 LoadTimingInfo load_timing_info;
4771 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4772 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4773
4774 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524775 ASSERT_TRUE(response);
4776 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:224777 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4778
4779 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294780 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504781 rv = trans->Read(buf.get(), 256, callback.callback());
4782 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224783
danakj1fd259a02016-04-16 03:17:094784 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504785 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224786 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504787 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224788
4789 LoadTimingInfo load_timing_info2;
4790 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4791 // Even though the SPDY connection is reused, a new tunnelled connection has
4792 // to be created, so the socket's load timing looks like a fresh connection.
4793 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
4794
4795 // The requests should have different IDs, since they each are using their own
4796 // separate stream.
4797 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4798
mmenke11eb5152015-06-09 14:50:504799 rv = trans2->Read(buf.get(), 256, callback.callback());
4800 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224801}
4802
4803// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4804// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:024805TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224806 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
4807 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034808 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514809 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074810 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094811 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504812 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224813
4814 HttpRequestInfo request1;
4815 request1.method = "GET";
bncce36dca22015-04-21 22:11:234816 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224817 request1.load_flags = 0;
4818
4819 HttpRequestInfo request2;
4820 request2.method = "GET";
bncce36dca22015-04-21 22:11:234821 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:224822 request2.load_flags = 0;
4823
bncce36dca22015-04-21 22:11:234824 // CONNECT to www.example.org:443 via SPDY.
danakj1fd259a02016-04-16 03:17:094825 std::unique_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234826 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:094827 std::unique_ptr<SpdySerializedFrame> conn_resp1(
[email protected]23e482282013-06-14 16:08:024828 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224829
bncce36dca22015-04-21 22:11:234830 // Fetch https://www.example.org/ via HTTP.
4831 const char get1[] =
4832 "GET / HTTP/1.1\r\n"
4833 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224834 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094835 std::unique_ptr<SpdySerializedFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024836 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224837 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4838 "Content-Length: 1\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094839 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024840 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
danakj1fd259a02016-04-16 03:17:094841 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
[email protected]23e482282013-06-14 16:08:024842 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
danakj1fd259a02016-04-16 03:17:094843 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204844 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224845
bncce36dca22015-04-21 22:11:234846 // Fetch https://www.example.org/2 via HTTP.
4847 const char get2[] =
4848 "GET /2 HTTP/1.1\r\n"
4849 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224850 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094851 std::unique_ptr<SpdySerializedFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024852 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224853 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4854 "Content-Length: 2\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094855 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024856 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
danakj1fd259a02016-04-16 03:17:094857 std::unique_ptr<SpdySerializedFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024858 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224859
4860 MockWrite spdy_writes[] = {
4861 CreateMockWrite(*connect1, 0),
4862 CreateMockWrite(*wrapped_get1, 2),
4863 CreateMockWrite(*wrapped_get2, 5),
4864 };
4865
4866 MockRead spdy_reads[] = {
4867 CreateMockRead(*conn_resp1, 1, ASYNC),
4868 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4869 CreateMockRead(*wrapped_body1, 4, ASYNC),
4870 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4871 CreateMockRead(*wrapped_body2, 7, ASYNC),
4872 MockRead(ASYNC, 0, 8),
4873 };
4874
mmenke11eb5152015-06-09 14:50:504875 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4876 arraysize(spdy_writes));
4877 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224878
4879 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384880 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:504881 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224882 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504883 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224884
4885 TestCompletionCallback callback;
4886
danakj1fd259a02016-04-16 03:17:094887 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504888 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224889 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4890 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224891
4892 rv = callback.WaitForResult();
4893 EXPECT_EQ(OK, rv);
4894
4895 LoadTimingInfo load_timing_info;
4896 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4897 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4898
4899 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524900 ASSERT_TRUE(response);
4901 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:224902 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4903
4904 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294905 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504906 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224907 trans.reset();
4908
danakj1fd259a02016-04-16 03:17:094909 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504910 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224911 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4912 EXPECT_EQ(ERR_IO_PENDING, rv);
4913
[email protected]f6c63db52013-02-02 00:35:224914 rv = callback.WaitForResult();
4915 EXPECT_EQ(OK, rv);
4916
4917 LoadTimingInfo load_timing_info2;
4918 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4919 TestLoadTimingReused(load_timing_info2);
4920
4921 // The requests should have the same ID.
4922 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4923
[email protected]90499482013-06-01 00:39:504924 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224925}
4926
4927// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4928// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504929TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224930 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034931 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514932 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074933 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094934 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504935 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224936
4937 HttpRequestInfo request1;
4938 request1.method = "GET";
bncce36dca22015-04-21 22:11:234939 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224940 request1.load_flags = 0;
4941
4942 HttpRequestInfo request2;
4943 request2.method = "GET";
bncce36dca22015-04-21 22:11:234944 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224945 request2.load_flags = 0;
4946
bncce36dca22015-04-21 22:11:234947 // http://www.example.org/
danakj1fd259a02016-04-16 03:17:094948 std::unique_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234949 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
danakj1fd259a02016-04-16 03:17:094950 std::unique_ptr<SpdySerializedFrame> get1(
bnc38dcd392016-02-09 23:19:494951 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
danakj1fd259a02016-04-16 03:17:094952 std::unique_ptr<SpdySerializedFrame> get_resp1(
[email protected]23e482282013-06-14 16:08:024953 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094954 std::unique_ptr<SpdySerializedFrame> body1(
[email protected]23e482282013-06-14 16:08:024955 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:384956 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:224957
bncce36dca22015-04-21 22:11:234958 // http://mail.example.org/
danakj1fd259a02016-04-16 03:17:094959 std::unique_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234960 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
danakj1fd259a02016-04-16 03:17:094961 std::unique_ptr<SpdySerializedFrame> get2(
bnc38dcd392016-02-09 23:19:494962 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, true));
danakj1fd259a02016-04-16 03:17:094963 std::unique_ptr<SpdySerializedFrame> get_resp2(
[email protected]23e482282013-06-14 16:08:024964 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:094965 std::unique_ptr<SpdySerializedFrame> body2(
[email protected]23e482282013-06-14 16:08:024966 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224967
4968 MockWrite spdy_writes[] = {
4969 CreateMockWrite(*get1, 0),
4970 CreateMockWrite(*get2, 3),
4971 };
4972
4973 MockRead spdy_reads[] = {
4974 CreateMockRead(*get_resp1, 1, ASYNC),
4975 CreateMockRead(*body1, 2, ASYNC),
4976 CreateMockRead(*get_resp2, 4, ASYNC),
4977 CreateMockRead(*body2, 5, ASYNC),
4978 MockRead(ASYNC, 0, 6),
4979 };
4980
mmenke11eb5152015-06-09 14:50:504981 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4982 arraysize(spdy_writes));
4983 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224984
4985 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384986 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:504987 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224988
4989 TestCompletionCallback callback;
4990
danakj1fd259a02016-04-16 03:17:094991 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504992 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224993 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504994 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224995
4996 LoadTimingInfo load_timing_info;
4997 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4998 TestLoadTimingNotReused(load_timing_info,
4999 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5000
5001 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525002 ASSERT_TRUE(response);
5003 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025004 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225005
5006 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295007 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505008 rv = trans->Read(buf.get(), 256, callback.callback());
5009 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225010 // Delete the first request, so the second one can reuse the socket.
5011 trans.reset();
5012
danakj1fd259a02016-04-16 03:17:095013 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:505014 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225015 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505016 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225017
5018 LoadTimingInfo load_timing_info2;
5019 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5020 TestLoadTimingReused(load_timing_info2);
5021
5022 // The requests should have the same ID.
5023 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5024
mmenke11eb5152015-06-09 14:50:505025 rv = trans2->Read(buf.get(), 256, callback.callback());
5026 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225027}
5028
[email protected]2df19bb2010-08-25 20:13:465029// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:025030TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465031 HttpRequestInfo request;
5032 request.method = "GET";
bncce36dca22015-04-21 22:11:235033 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465034 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295035 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465036
[email protected]79cb5c12011-09-12 13:12:045037 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035038 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515039 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075040 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275042
[email protected]2df19bb2010-08-25 20:13:465043 // Since we have proxy, should use full url
5044 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235045 MockWrite(
5046 "GET http://www.example.org/ HTTP/1.1\r\n"
5047 "Host: www.example.org\r\n"
5048 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465049
bncce36dca22015-04-21 22:11:235050 // After calling trans->RestartWithAuth(), this is the request we should
5051 // be issuing -- the final header line contains the credentials.
5052 MockWrite(
5053 "GET http://www.example.org/ HTTP/1.1\r\n"
5054 "Host: www.example.org\r\n"
5055 "Proxy-Connection: keep-alive\r\n"
5056 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465057 };
5058
5059 // The proxy responds to the GET with a 407, using a persistent
5060 // connection.
5061 MockRead data_reads1[] = {
5062 // No credentials.
5063 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5064 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5065 MockRead("Proxy-Connection: keep-alive\r\n"),
5066 MockRead("Content-Length: 0\r\n\r\n"),
5067
5068 MockRead("HTTP/1.1 200 OK\r\n"),
5069 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5070 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065071 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465072 };
5073
5074 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5075 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075076 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065077 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075078 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465079
[email protected]49639fa2011-12-20 23:22:415080 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465081
danakj1fd259a02016-04-16 03:17:095082 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505083 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505084
[email protected]49639fa2011-12-20 23:22:415085 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:465086 EXPECT_EQ(ERR_IO_PENDING, rv);
5087
5088 rv = callback1.WaitForResult();
5089 EXPECT_EQ(OK, rv);
5090
[email protected]58e32bb2013-01-21 18:23:255091 LoadTimingInfo load_timing_info;
5092 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5093 TestLoadTimingNotReused(load_timing_info,
5094 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5095
[email protected]2df19bb2010-08-25 20:13:465096 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525097 ASSERT_TRUE(response);
5098 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465099 EXPECT_EQ(407, response->headers->response_code());
5100 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:045101 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465102
[email protected]49639fa2011-12-20 23:22:415103 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465104
[email protected]49639fa2011-12-20 23:22:415105 rv = trans->RestartWithAuth(
5106 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:465107 EXPECT_EQ(ERR_IO_PENDING, rv);
5108
5109 rv = callback2.WaitForResult();
5110 EXPECT_EQ(OK, rv);
5111
[email protected]58e32bb2013-01-21 18:23:255112 load_timing_info = LoadTimingInfo();
5113 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5114 // Retrying with HTTP AUTH is considered to be reusing a socket.
5115 TestLoadTimingReused(load_timing_info);
5116
[email protected]2df19bb2010-08-25 20:13:465117 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525118 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465119
5120 EXPECT_TRUE(response->headers->IsKeepAlive());
5121 EXPECT_EQ(200, response->headers->response_code());
5122 EXPECT_EQ(100, response->headers->GetContentLength());
5123 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5124
5125 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525126 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465127}
5128
[email protected]23e482282013-06-14 16:08:025129void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085130 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425131 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085132 request.method = "GET";
bncce36dca22015-04-21 22:11:235133 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085134 request.load_flags = 0;
5135
[email protected]cb9bf6ca2011-01-28 13:15:275136 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035137 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095138 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275139
[email protected]c744cf22009-02-27 07:28:085140 // Since we have proxy, should try to establish tunnel.
5141 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175142 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5143 "Host: www.example.org:443\r\n"
5144 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085145 };
5146
5147 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235148 status, MockRead("Content-Length: 10\r\n\r\n"),
5149 // No response body because the test stops reading here.
5150 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085151 };
5152
[email protected]31a2bfe2010-02-09 08:03:395153 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5154 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075155 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085156
[email protected]49639fa2011-12-20 23:22:415157 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085158
danakj1fd259a02016-04-16 03:17:095159 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505160 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505161
[email protected]49639fa2011-12-20 23:22:415162 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425163 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:085164
5165 rv = callback.WaitForResult();
5166 EXPECT_EQ(expected_status, rv);
5167}
5168
[email protected]23e482282013-06-14 16:08:025169void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235170 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085171 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425172 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085173}
5174
[email protected]23e482282013-06-14 16:08:025175TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085176 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5177}
5178
[email protected]23e482282013-06-14 16:08:025179TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085180 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5181}
5182
[email protected]23e482282013-06-14 16:08:025183TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085184 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5185}
5186
[email protected]23e482282013-06-14 16:08:025187TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085188 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5189}
5190
[email protected]23e482282013-06-14 16:08:025191TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085192 ConnectStatusHelper(
5193 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5194}
5195
[email protected]23e482282013-06-14 16:08:025196TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085197 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5198}
5199
[email protected]23e482282013-06-14 16:08:025200TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085201 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5202}
5203
[email protected]23e482282013-06-14 16:08:025204TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085205 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5206}
5207
[email protected]23e482282013-06-14 16:08:025208TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085209 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5210}
5211
[email protected]23e482282013-06-14 16:08:025212TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085213 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5214}
5215
[email protected]23e482282013-06-14 16:08:025216TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085217 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5218}
5219
[email protected]23e482282013-06-14 16:08:025220TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085221 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5222}
5223
[email protected]23e482282013-06-14 16:08:025224TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085225 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5226}
5227
[email protected]23e482282013-06-14 16:08:025228TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085229 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5230}
5231
[email protected]23e482282013-06-14 16:08:025232TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085233 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5234}
5235
[email protected]23e482282013-06-14 16:08:025236TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085237 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5238}
5239
[email protected]0a17aab32014-04-24 03:32:375240TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
5241 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5242}
5243
[email protected]23e482282013-06-14 16:08:025244TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085245 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5246}
5247
[email protected]23e482282013-06-14 16:08:025248TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085249 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5250}
5251
[email protected]23e482282013-06-14 16:08:025252TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085253 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5254}
5255
[email protected]23e482282013-06-14 16:08:025256TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085257 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5258}
5259
[email protected]23e482282013-06-14 16:08:025260TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085261 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5262}
5263
[email protected]23e482282013-06-14 16:08:025264TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085265 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5266}
5267
[email protected]23e482282013-06-14 16:08:025268TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085269 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5270}
5271
[email protected]23e482282013-06-14 16:08:025272TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085273 ConnectStatusHelperWithExpectedStatus(
5274 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545275 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085276}
5277
[email protected]23e482282013-06-14 16:08:025278TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085279 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5280}
5281
[email protected]23e482282013-06-14 16:08:025282TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085283 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5284}
5285
[email protected]23e482282013-06-14 16:08:025286TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085287 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5288}
5289
[email protected]23e482282013-06-14 16:08:025290TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085291 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5292}
5293
[email protected]23e482282013-06-14 16:08:025294TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085295 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5296}
5297
[email protected]23e482282013-06-14 16:08:025298TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085299 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5300}
5301
[email protected]23e482282013-06-14 16:08:025302TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085303 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5304}
5305
[email protected]23e482282013-06-14 16:08:025306TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085307 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5308}
5309
[email protected]23e482282013-06-14 16:08:025310TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085311 ConnectStatusHelper(
5312 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5313}
5314
[email protected]23e482282013-06-14 16:08:025315TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085316 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5317}
5318
[email protected]23e482282013-06-14 16:08:025319TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085320 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5321}
5322
[email protected]23e482282013-06-14 16:08:025323TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085324 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5325}
5326
[email protected]23e482282013-06-14 16:08:025327TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085328 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5329}
5330
[email protected]23e482282013-06-14 16:08:025331TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085332 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5333}
5334
[email protected]23e482282013-06-14 16:08:025335TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085336 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5337}
5338
[email protected]23e482282013-06-14 16:08:025339TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085340 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5341}
5342
[email protected]038e9a32008-10-08 22:40:165343// Test the flow when both the proxy server AND origin server require
5344// authentication. Again, this uses basic auth for both since that is
5345// the simplest to mock.
[email protected]23e482282013-06-14 16:08:025346TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275347 HttpRequestInfo request;
5348 request.method = "GET";
bncce36dca22015-04-21 22:11:235349 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275350 request.load_flags = 0;
5351
[email protected]038e9a32008-10-08 22:40:165352 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035353 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075355
danakj1fd259a02016-04-16 03:17:095356 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415357 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:165358
[email protected]f9ee6b52008-11-08 06:46:235359 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235360 MockWrite(
5361 "GET http://www.example.org/ HTTP/1.1\r\n"
5362 "Host: www.example.org\r\n"
5363 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235364 };
5365
[email protected]038e9a32008-10-08 22:40:165366 MockRead data_reads1[] = {
5367 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5368 // Give a couple authenticate options (only the middle one is actually
5369 // supported).
[email protected]22927ad2009-09-21 19:56:195370 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165371 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5372 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5373 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5374 // Large content-length -- won't matter, as connection will be reset.
5375 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065376 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165377 };
5378
5379 // After calling trans->RestartWithAuth() the first time, this is the
5380 // request we should be issuing -- the final header line contains the
5381 // proxy's credentials.
5382 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235383 MockWrite(
5384 "GET http://www.example.org/ HTTP/1.1\r\n"
5385 "Host: www.example.org\r\n"
5386 "Proxy-Connection: keep-alive\r\n"
5387 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165388 };
5389
5390 // Now the proxy server lets the request pass through to origin server.
5391 // The origin server responds with a 401.
5392 MockRead data_reads2[] = {
5393 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5394 // Note: We are using the same realm-name as the proxy server. This is
5395 // completely valid, as realms are unique across hosts.
5396 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5397 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5398 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065399 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165400 };
5401
5402 // After calling trans->RestartWithAuth() the second time, we should send
5403 // the credentials for both the proxy and origin server.
5404 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235405 MockWrite(
5406 "GET http://www.example.org/ HTTP/1.1\r\n"
5407 "Host: www.example.org\r\n"
5408 "Proxy-Connection: keep-alive\r\n"
5409 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5410 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165411 };
5412
5413 // Lastly we get the desired content.
5414 MockRead data_reads3[] = {
5415 MockRead("HTTP/1.0 200 OK\r\n"),
5416 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5417 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065418 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165419 };
5420
[email protected]31a2bfe2010-02-09 08:03:395421 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5422 data_writes1, arraysize(data_writes1));
5423 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5424 data_writes2, arraysize(data_writes2));
5425 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5426 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075427 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5428 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5429 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165430
[email protected]49639fa2011-12-20 23:22:415431 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165432
[email protected]49639fa2011-12-20 23:22:415433 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425434 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165435
5436 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425437 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165438
[email protected]1c773ea12009-04-28 19:58:425439 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525440 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045441 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165442
[email protected]49639fa2011-12-20 23:22:415443 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165444
[email protected]49639fa2011-12-20 23:22:415445 rv = trans->RestartWithAuth(
5446 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425447 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165448
5449 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425450 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165451
5452 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525453 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045454 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165455
[email protected]49639fa2011-12-20 23:22:415456 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165457
[email protected]49639fa2011-12-20 23:22:415458 rv = trans->RestartWithAuth(
5459 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425460 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165461
5462 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425463 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165464
5465 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525466 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165467 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165468}
[email protected]4ddaf2502008-10-23 18:26:195469
[email protected]ea9dc9a2009-09-05 00:43:325470// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5471// can't hook into its internals to cause it to generate predictable NTLM
5472// authorization headers.
5473#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295474// The NTLM authentication unit tests were generated by capturing the HTTP
5475// requests and responses using Fiddler 2 and inspecting the generated random
5476// bytes in the debugger.
5477
5478// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:025479TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425480 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245481 request.method = "GET";
5482 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545483
5484 // Ensure load is not disrupted by flags which suppress behaviour specific
5485 // to other auth schemes.
5486 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245487
[email protected]cb9bf6ca2011-01-28 13:15:275488 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5489 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095490 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275491
[email protected]3f918782009-02-28 01:29:245492 MockWrite data_writes1[] = {
5493 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5494 "Host: 172.22.68.17\r\n"
5495 "Connection: keep-alive\r\n\r\n"),
5496 };
5497
5498 MockRead data_reads1[] = {
5499 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045500 // Negotiate and NTLM are often requested together. However, we only want
5501 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5502 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245503 MockRead("WWW-Authenticate: NTLM\r\n"),
5504 MockRead("Connection: close\r\n"),
5505 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365506 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245507 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065508 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245509 };
5510
5511 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225512 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:245513 // request we should be issuing -- the final header line contains a Type
5514 // 1 message.
5515 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5516 "Host: 172.22.68.17\r\n"
5517 "Connection: keep-alive\r\n"
5518 "Authorization: NTLM "
5519 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5520
5521 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5522 // (the credentials for the origin server). The second request continues
5523 // on the same connection.
5524 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5525 "Host: 172.22.68.17\r\n"
5526 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:295527 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5528 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5529 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5530 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5531 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245532 };
5533
5534 MockRead data_reads2[] = {
5535 // The origin server responds with a Type 2 message.
5536 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5537 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295538 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245539 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5540 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5541 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5542 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5543 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5544 "BtAAAAAAA=\r\n"),
5545 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365546 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245547 MockRead("You are not authorized to view this page\r\n"),
5548
5549 // Lastly we get the desired content.
5550 MockRead("HTTP/1.1 200 OK\r\n"),
5551 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5552 MockRead("Content-Length: 13\r\n\r\n"),
5553 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065554 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245555 };
5556
[email protected]31a2bfe2010-02-09 08:03:395557 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5558 data_writes1, arraysize(data_writes1));
5559 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5560 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075561 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5562 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245563
[email protected]49639fa2011-12-20 23:22:415564 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245565
danakj1fd259a02016-04-16 03:17:095566 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505567 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505568
[email protected]49639fa2011-12-20 23:22:415569 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425570 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245571
5572 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425573 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245574
[email protected]0757e7702009-03-27 04:00:225575 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5576
[email protected]1c773ea12009-04-28 19:58:425577 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525578 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045579 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245580
[email protected]49639fa2011-12-20 23:22:415581 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255582
[email protected]f3cf9802011-10-28 18:44:585583 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415584 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:255585 EXPECT_EQ(ERR_IO_PENDING, rv);
5586
5587 rv = callback2.WaitForResult();
5588 EXPECT_EQ(OK, rv);
5589
5590 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5591
5592 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525593 ASSERT_TRUE(response);
5594 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255595
[email protected]49639fa2011-12-20 23:22:415596 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245597
[email protected]49639fa2011-12-20 23:22:415598 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425599 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245600
[email protected]0757e7702009-03-27 04:00:225601 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425602 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245603
5604 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525605 ASSERT_TRUE(response);
5606 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245607 EXPECT_EQ(13, response->headers->GetContentLength());
5608}
5609
[email protected]385a4672009-03-11 22:21:295610// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:025611TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425612 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295613 request.method = "GET";
5614 request.url = GURL("http://172.22.68.17/kids/login.aspx");
5615 request.load_flags = 0;
5616
[email protected]cb9bf6ca2011-01-28 13:15:275617 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5618 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095619 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275620
[email protected]385a4672009-03-11 22:21:295621 MockWrite data_writes1[] = {
5622 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5623 "Host: 172.22.68.17\r\n"
5624 "Connection: keep-alive\r\n\r\n"),
5625 };
5626
5627 MockRead data_reads1[] = {
5628 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045629 // Negotiate and NTLM are often requested together. However, we only want
5630 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5631 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:295632 MockRead("WWW-Authenticate: NTLM\r\n"),
5633 MockRead("Connection: close\r\n"),
5634 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365635 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295636 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065637 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295638 };
5639
5640 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225641 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295642 // request we should be issuing -- the final header line contains a Type
5643 // 1 message.
5644 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5645 "Host: 172.22.68.17\r\n"
5646 "Connection: keep-alive\r\n"
5647 "Authorization: NTLM "
5648 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5649
5650 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5651 // (the credentials for the origin server). The second request continues
5652 // on the same connection.
5653 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5654 "Host: 172.22.68.17\r\n"
5655 "Connection: keep-alive\r\n"
5656 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5657 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5658 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
5659 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
5660 "4Ww7b7E=\r\n\r\n"),
5661 };
5662
5663 MockRead data_reads2[] = {
5664 // The origin server responds with a Type 2 message.
5665 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5666 MockRead("WWW-Authenticate: NTLM "
5667 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
5668 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5669 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5670 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5671 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5672 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5673 "BtAAAAAAA=\r\n"),
5674 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365675 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295676 MockRead("You are not authorized to view this page\r\n"),
5677
5678 // Wrong password.
5679 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:295680 MockRead("WWW-Authenticate: NTLM\r\n"),
5681 MockRead("Connection: close\r\n"),
5682 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365683 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295684 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065685 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295686 };
5687
5688 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:225689 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295690 // request we should be issuing -- the final header line contains a Type
5691 // 1 message.
5692 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5693 "Host: 172.22.68.17\r\n"
5694 "Connection: keep-alive\r\n"
5695 "Authorization: NTLM "
5696 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5697
5698 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5699 // (the credentials for the origin server). The second request continues
5700 // on the same connection.
5701 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5702 "Host: 172.22.68.17\r\n"
5703 "Connection: keep-alive\r\n"
5704 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5705 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5706 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
5707 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
5708 "+4MUm7c=\r\n\r\n"),
5709 };
5710
5711 MockRead data_reads3[] = {
5712 // The origin server responds with a Type 2 message.
5713 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5714 MockRead("WWW-Authenticate: NTLM "
5715 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
5716 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5717 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5718 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5719 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5720 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5721 "BtAAAAAAA=\r\n"),
5722 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365723 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295724 MockRead("You are not authorized to view this page\r\n"),
5725
5726 // Lastly we get the desired content.
5727 MockRead("HTTP/1.1 200 OK\r\n"),
5728 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5729 MockRead("Content-Length: 13\r\n\r\n"),
5730 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065731 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:295732 };
5733
[email protected]31a2bfe2010-02-09 08:03:395734 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5735 data_writes1, arraysize(data_writes1));
5736 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5737 data_writes2, arraysize(data_writes2));
5738 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5739 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075740 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5741 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5742 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:295743
[email protected]49639fa2011-12-20 23:22:415744 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:295745
danakj1fd259a02016-04-16 03:17:095746 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505747 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505748
[email protected]49639fa2011-12-20 23:22:415749 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425750 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295751
5752 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425753 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295754
[email protected]0757e7702009-03-27 04:00:225755 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:295756
[email protected]1c773ea12009-04-28 19:58:425757 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525758 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045759 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:295760
[email protected]49639fa2011-12-20 23:22:415761 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:295762
[email protected]0757e7702009-03-27 04:00:225763 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:585764 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:415765 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425766 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295767
[email protected]10af5fe72011-01-31 16:17:255768 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425769 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295770
[email protected]0757e7702009-03-27 04:00:225771 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415772 TestCompletionCallback callback3;
5773 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425774 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:255775 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425776 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225777 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5778
5779 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525780 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045781 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:225782
[email protected]49639fa2011-12-20 23:22:415783 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:225784
5785 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:585786 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415787 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:255788 EXPECT_EQ(ERR_IO_PENDING, rv);
5789
5790 rv = callback4.WaitForResult();
5791 EXPECT_EQ(OK, rv);
5792
5793 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5794
[email protected]49639fa2011-12-20 23:22:415795 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:255796
5797 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:415798 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:425799 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225800
5801 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425802 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225803
[email protected]385a4672009-03-11 22:21:295804 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525805 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:295806 EXPECT_EQ(13, response->headers->GetContentLength());
5807}
[email protected]ea9dc9a2009-09-05 00:43:325808#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:295809
[email protected]4ddaf2502008-10-23 18:26:195810// Test reading a server response which has only headers, and no body.
5811// After some maximum number of bytes is consumed, the transaction should
5812// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:025813TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:425814 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:195815 request.method = "GET";
bncce36dca22015-04-21 22:11:235816 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:195817 request.load_flags = 0;
5818
danakj1fd259a02016-04-16 03:17:095819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5820 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415821 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275822
[email protected]b75b7b2f2009-10-06 00:54:535823 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:435824 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:535825 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:195826
5827 MockRead data_reads[] = {
5828 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065829 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:195830 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:065831 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:195832 };
[email protected]31a2bfe2010-02-09 08:03:395833 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075834 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:195835
[email protected]49639fa2011-12-20 23:22:415836 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195837
[email protected]49639fa2011-12-20 23:22:415838 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425839 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195840
5841 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425842 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195843}
[email protected]f4e426b2008-11-05 00:24:495844
5845// Make sure that we don't try to reuse a TCPClientSocket when failing to
5846// establish tunnel.
5847// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025848TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235849 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275850 HttpRequestInfo request;
5851 request.method = "GET";
bncce36dca22015-04-21 22:11:235852 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275853 request.load_flags = 0;
5854
[email protected]f4e426b2008-11-05 00:24:495855 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035856 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:015857
danakj1fd259a02016-04-16 03:17:095858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495859
danakj1fd259a02016-04-16 03:17:095860 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505861 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495862
[email protected]f4e426b2008-11-05 00:24:495863 // Since we have proxy, should try to establish tunnel.
5864 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175865 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5866 "Host: www.example.org:443\r\n"
5867 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495868 };
5869
[email protected]77848d12008-11-14 00:00:225870 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495871 // connection. Usually a proxy would return 501 (not implemented),
5872 // or 200 (tunnel established).
5873 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:235874 MockRead("HTTP/1.1 404 Not Found\r\n"),
5875 MockRead("Content-Length: 10\r\n\r\n"),
5876 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:495877 };
5878
[email protected]31a2bfe2010-02-09 08:03:395879 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5880 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075881 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495882
[email protected]49639fa2011-12-20 23:22:415883 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495884
[email protected]49639fa2011-12-20 23:22:415885 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425886 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495887
5888 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425889 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495890
[email protected]b4404c02009-04-10 16:38:525891 // Empty the current queue. This is necessary because idle sockets are
5892 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345893 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525894
[email protected]f4e426b2008-11-05 00:24:495895 // We now check to make sure the TCPClientSocket was not added back to
5896 // the pool.
[email protected]90499482013-06-01 00:39:505897 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495898 trans.reset();
[email protected]2da659e2013-05-23 20:51:345899 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495900 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505901 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495902}
[email protected]372d34a2008-11-05 21:30:515903
[email protected]1b157c02009-04-21 01:55:405904// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025905TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425906 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405907 request.method = "GET";
bncce36dca22015-04-21 22:11:235908 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405909 request.load_flags = 0;
5910
danakj1fd259a02016-04-16 03:17:095911 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275912
danakj1fd259a02016-04-16 03:17:095913 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505914 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275915
[email protected]1b157c02009-04-21 01:55:405916 MockRead data_reads[] = {
5917 // A part of the response body is received with the response headers.
5918 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5919 // The rest of the response body is received in two parts.
5920 MockRead("lo"),
5921 MockRead(" world"),
5922 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065923 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405924 };
5925
[email protected]31a2bfe2010-02-09 08:03:395926 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075927 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405928
[email protected]49639fa2011-12-20 23:22:415929 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405930
[email protected]49639fa2011-12-20 23:22:415931 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425932 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405933
5934 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425935 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405936
[email protected]1c773ea12009-04-28 19:58:425937 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525938 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:405939
wezca1070932016-05-26 20:30:525940 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:405941 std::string status_line = response->headers->GetStatusLine();
5942 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5943
[email protected]90499482013-06-01 00:39:505944 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405945
5946 std::string response_data;
5947 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425948 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405949 EXPECT_EQ("hello world", response_data);
5950
5951 // Empty the current queue. This is necessary because idle sockets are
5952 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345953 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405954
5955 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505956 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405957}
5958
[email protected]76a505b2010-08-25 06:23:005959// Make sure that we recycle a SSL socket after reading all of the response
5960// body.
[email protected]23e482282013-06-14 16:08:025961TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005962 HttpRequestInfo request;
5963 request.method = "GET";
bncce36dca22015-04-21 22:11:235964 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005965 request.load_flags = 0;
5966
5967 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235968 MockWrite(
5969 "GET / HTTP/1.1\r\n"
5970 "Host: www.example.org\r\n"
5971 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005972 };
5973
5974 MockRead data_reads[] = {
5975 MockRead("HTTP/1.1 200 OK\r\n"),
5976 MockRead("Content-Length: 11\r\n\r\n"),
5977 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065978 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005979 };
5980
[email protected]8ddf8322012-02-23 18:08:065981 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075982 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005983
5984 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5985 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075986 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005987
[email protected]49639fa2011-12-20 23:22:415988 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005989
danakj1fd259a02016-04-16 03:17:095990 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5991 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505992 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005993
[email protected]49639fa2011-12-20 23:22:415994 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005995
5996 EXPECT_EQ(ERR_IO_PENDING, rv);
5997 EXPECT_EQ(OK, callback.WaitForResult());
5998
5999 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526000 ASSERT_TRUE(response);
6001 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006002 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6003
[email protected]90499482013-06-01 00:39:506004 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006005
6006 std::string response_data;
6007 rv = ReadTransaction(trans.get(), &response_data);
6008 EXPECT_EQ(OK, rv);
6009 EXPECT_EQ("hello world", response_data);
6010
6011 // Empty the current queue. This is necessary because idle sockets are
6012 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:346013 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006014
6015 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506016 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006017}
6018
6019// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6020// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:026021TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006022 HttpRequestInfo request;
6023 request.method = "GET";
bncce36dca22015-04-21 22:11:236024 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006025 request.load_flags = 0;
6026
6027 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236028 MockWrite(
6029 "GET / HTTP/1.1\r\n"
6030 "Host: www.example.org\r\n"
6031 "Connection: keep-alive\r\n\r\n"),
6032 MockWrite(
6033 "GET / HTTP/1.1\r\n"
6034 "Host: www.example.org\r\n"
6035 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006036 };
6037
6038 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426039 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6040 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006041
[email protected]8ddf8322012-02-23 18:08:066042 SSLSocketDataProvider ssl(ASYNC, OK);
6043 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076044 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6045 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006046
6047 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6048 data_writes, arraysize(data_writes));
6049 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6050 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076051 session_deps_.socket_factory->AddSocketDataProvider(&data);
6052 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006053
[email protected]49639fa2011-12-20 23:22:416054 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006055
danakj1fd259a02016-04-16 03:17:096056 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6057 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506058 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006059
[email protected]49639fa2011-12-20 23:22:416060 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006061
6062 EXPECT_EQ(ERR_IO_PENDING, rv);
6063 EXPECT_EQ(OK, callback.WaitForResult());
6064
6065 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526066 ASSERT_TRUE(response);
6067 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006068 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6069
[email protected]90499482013-06-01 00:39:506070 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006071
6072 std::string response_data;
6073 rv = ReadTransaction(trans.get(), &response_data);
6074 EXPECT_EQ(OK, rv);
6075 EXPECT_EQ("hello world", response_data);
6076
6077 // Empty the current queue. This is necessary because idle sockets are
6078 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:346079 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006080
6081 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506082 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006083
6084 // Now start the second transaction, which should reuse the previous socket.
6085
[email protected]90499482013-06-01 00:39:506086 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006087
[email protected]49639fa2011-12-20 23:22:416088 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006089
6090 EXPECT_EQ(ERR_IO_PENDING, rv);
6091 EXPECT_EQ(OK, callback.WaitForResult());
6092
6093 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526094 ASSERT_TRUE(response);
6095 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006096 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6097
[email protected]90499482013-06-01 00:39:506098 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006099
6100 rv = ReadTransaction(trans.get(), &response_data);
6101 EXPECT_EQ(OK, rv);
6102 EXPECT_EQ("hello world", response_data);
6103
6104 // Empty the current queue. This is necessary because idle sockets are
6105 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:346106 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006107
6108 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506109 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006110}
6111
[email protected]b4404c02009-04-10 16:38:526112// Make sure that we recycle a socket after a zero-length response.
6113// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:026114TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426115 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526116 request.method = "GET";
bncce36dca22015-04-21 22:11:236117 request.url = GURL(
6118 "http://www.example.org/csi?v=3&s=web&action=&"
6119 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6120 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6121 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526122 request.load_flags = 0;
6123
danakj1fd259a02016-04-16 03:17:096124 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276125
[email protected]b4404c02009-04-10 16:38:526126 MockRead data_reads[] = {
6127 MockRead("HTTP/1.1 204 No Content\r\n"
6128 "Content-Length: 0\r\n"
6129 "Content-Type: text/html\r\n\r\n"),
6130 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066131 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526132 };
6133
[email protected]31a2bfe2010-02-09 08:03:396134 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076135 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526136
mmenkecc2298e2015-12-07 18:20:186137 // Transaction must be created after the MockReads, so it's destroyed before
6138 // them.
danakj1fd259a02016-04-16 03:17:096139 std::unique_ptr<HttpTransaction> trans(
mmenkecc2298e2015-12-07 18:20:186140 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6141
[email protected]49639fa2011-12-20 23:22:416142 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526143
[email protected]49639fa2011-12-20 23:22:416144 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426145 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:526146
6147 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426148 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:526149
[email protected]1c773ea12009-04-28 19:58:426150 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526151 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526152
wezca1070932016-05-26 20:30:526153 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526154 std::string status_line = response->headers->GetStatusLine();
6155 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6156
[email protected]90499482013-06-01 00:39:506157 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526158
6159 std::string response_data;
6160 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426161 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:526162 EXPECT_EQ("", response_data);
6163
6164 // Empty the current queue. This is necessary because idle sockets are
6165 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:346166 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526167
6168 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506169 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526170}
6171
[email protected]23e482282013-06-14 16:08:026172TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096173 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226174 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:096175 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:226176 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276177
[email protected]1c773ea12009-04-28 19:58:426178 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516179 // Transaction 1: a GET request that succeeds. The socket is recycled
6180 // after use.
6181 request[0].method = "GET";
6182 request[0].url = GURL("http://www.google.com/");
6183 request[0].load_flags = 0;
6184 // Transaction 2: a POST request. Reuses the socket kept alive from
6185 // transaction 1. The first attempts fails when writing the POST data.
6186 // This causes the transaction to retry with a new socket. The second
6187 // attempt succeeds.
6188 request[1].method = "POST";
6189 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276190 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516191 request[1].load_flags = 0;
6192
danakj1fd259a02016-04-16 03:17:096193 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516194
6195 // The first socket is used for transaction 1 and the first attempt of
6196 // transaction 2.
6197
6198 // The response of transaction 1.
6199 MockRead data_reads1[] = {
6200 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6201 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066202 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516203 };
6204 // The mock write results of transaction 1 and the first attempt of
6205 // transaction 2.
6206 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066207 MockWrite(SYNCHRONOUS, 64), // GET
6208 MockWrite(SYNCHRONOUS, 93), // POST
6209 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516210 };
[email protected]31a2bfe2010-02-09 08:03:396211 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6212 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516213
6214 // The second socket is used for the second attempt of transaction 2.
6215
6216 // The response of transaction 2.
6217 MockRead data_reads2[] = {
6218 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6219 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066220 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516221 };
6222 // The mock write results of the second attempt of transaction 2.
6223 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066224 MockWrite(SYNCHRONOUS, 93), // POST
6225 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516226 };
[email protected]31a2bfe2010-02-09 08:03:396227 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6228 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516229
[email protected]bb88e1d32013-05-03 23:11:076230 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6231 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516232
thestig9d3bb0c2015-01-24 00:49:516233 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516234 "hello world", "welcome"
6235 };
6236
6237 for (int i = 0; i < 2; ++i) {
danakj1fd259a02016-04-16 03:17:096238 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506239 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:516240
[email protected]49639fa2011-12-20 23:22:416241 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516242
[email protected]49639fa2011-12-20 23:22:416243 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426244 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:516245
6246 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426247 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516248
[email protected]1c773ea12009-04-28 19:58:426249 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526250 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516251
wezca1070932016-05-26 20:30:526252 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516253 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6254
6255 std::string response_data;
6256 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426257 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516258 EXPECT_EQ(kExpectedResponseData[i], response_data);
6259 }
6260}
[email protected]f9ee6b52008-11-08 06:46:236261
6262// Test the request-challenge-retry sequence for basic auth when there is
6263// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166264// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:026265TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426266 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236267 request.method = "GET";
bncce36dca22015-04-21 22:11:236268 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416269 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296270
danakj1fd259a02016-04-16 03:17:096271 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6272 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416273 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276274
[email protected]a97cca42009-08-14 01:00:296275 // The password contains an escaped character -- for this test to pass it
6276 // will need to be unescaped by HttpNetworkTransaction.
6277 EXPECT_EQ("b%40r", request.url.password());
6278
[email protected]f9ee6b52008-11-08 06:46:236279 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236280 MockWrite(
6281 "GET / HTTP/1.1\r\n"
6282 "Host: www.example.org\r\n"
6283 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236284 };
6285
6286 MockRead data_reads1[] = {
6287 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6288 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6289 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066290 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236291 };
6292
[email protected]2262e3a2012-05-22 16:08:166293 // After the challenge above, the transaction will be restarted using the
6294 // identity from the url (foo, b@r) to answer the challenge.
6295 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236296 MockWrite(
6297 "GET / HTTP/1.1\r\n"
6298 "Host: www.example.org\r\n"
6299 "Connection: keep-alive\r\n"
6300 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166301 };
6302
6303 MockRead data_reads2[] = {
6304 MockRead("HTTP/1.0 200 OK\r\n"),
6305 MockRead("Content-Length: 100\r\n\r\n"),
6306 MockRead(SYNCHRONOUS, OK),
6307 };
6308
[email protected]31a2bfe2010-02-09 08:03:396309 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6310 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166311 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6312 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076313 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6314 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236315
[email protected]49639fa2011-12-20 23:22:416316 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:416317 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426318 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236319 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426320 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:166321 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6322
6323 TestCompletionCallback callback2;
6324 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6325 EXPECT_EQ(ERR_IO_PENDING, rv);
6326 rv = callback2.WaitForResult();
6327 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226328 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6329
[email protected]2262e3a2012-05-22 16:08:166330 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526331 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166332
6333 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526334 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166335
6336 EXPECT_EQ(100, response->headers->GetContentLength());
6337
6338 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:346339 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166340}
6341
6342// Test the request-challenge-retry sequence for basic auth when there is an
6343// incorrect identity in the URL. The identity from the URL should be used only
6344// once.
[email protected]23e482282013-06-14 16:08:026345TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166346 HttpRequestInfo request;
6347 request.method = "GET";
6348 // Note: the URL has a username:password in it. The password "baz" is
6349 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236350 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166351
6352 request.load_flags = LOAD_NORMAL;
6353
danakj1fd259a02016-04-16 03:17:096354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6355 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416356 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:166357
6358 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236359 MockWrite(
6360 "GET / HTTP/1.1\r\n"
6361 "Host: www.example.org\r\n"
6362 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166363 };
6364
6365 MockRead data_reads1[] = {
6366 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6367 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6368 MockRead("Content-Length: 10\r\n\r\n"),
6369 MockRead(SYNCHRONOUS, ERR_FAILED),
6370 };
6371
6372 // After the challenge above, the transaction will be restarted using the
6373 // identity from the url (foo, baz) to answer the challenge.
6374 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236375 MockWrite(
6376 "GET / HTTP/1.1\r\n"
6377 "Host: www.example.org\r\n"
6378 "Connection: keep-alive\r\n"
6379 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166380 };
6381
6382 MockRead data_reads2[] = {
6383 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6384 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6385 MockRead("Content-Length: 10\r\n\r\n"),
6386 MockRead(SYNCHRONOUS, ERR_FAILED),
6387 };
6388
6389 // After the challenge above, the transaction will be restarted using the
6390 // identity supplied by the user (foo, bar) to answer the challenge.
6391 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236392 MockWrite(
6393 "GET / HTTP/1.1\r\n"
6394 "Host: www.example.org\r\n"
6395 "Connection: keep-alive\r\n"
6396 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166397 };
6398
6399 MockRead data_reads3[] = {
6400 MockRead("HTTP/1.0 200 OK\r\n"),
6401 MockRead("Content-Length: 100\r\n\r\n"),
6402 MockRead(SYNCHRONOUS, OK),
6403 };
6404
6405 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6406 data_writes1, arraysize(data_writes1));
6407 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6408 data_writes2, arraysize(data_writes2));
6409 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6410 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076411 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6412 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6413 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166414
6415 TestCompletionCallback callback1;
6416
6417 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6418 EXPECT_EQ(ERR_IO_PENDING, rv);
6419
6420 rv = callback1.WaitForResult();
6421 EXPECT_EQ(OK, rv);
6422
6423 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6424 TestCompletionCallback callback2;
6425 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6426 EXPECT_EQ(ERR_IO_PENDING, rv);
6427 rv = callback2.WaitForResult();
6428 EXPECT_EQ(OK, rv);
6429 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6430
6431 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526432 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166433 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6434
6435 TestCompletionCallback callback3;
6436 rv = trans->RestartWithAuth(
6437 AuthCredentials(kFoo, kBar), callback3.callback());
6438 EXPECT_EQ(ERR_IO_PENDING, rv);
6439 rv = callback3.WaitForResult();
6440 EXPECT_EQ(OK, rv);
6441 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6442
6443 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526444 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166445
6446 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526447 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166448
6449 EXPECT_EQ(100, response->headers->GetContentLength());
6450
[email protected]ea9dc9a2009-09-05 00:43:326451 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:346452 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326453}
6454
[email protected]2217aa22013-10-11 03:03:546455
6456// Test the request-challenge-retry sequence for basic auth when there is a
6457// correct identity in the URL, but its use is being suppressed. The identity
6458// from the URL should never be used.
6459TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
6460 HttpRequestInfo request;
6461 request.method = "GET";
bncce36dca22015-04-21 22:11:236462 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546463 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6464
danakj1fd259a02016-04-16 03:17:096465 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6466 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416467 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:546468
6469 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236470 MockWrite(
6471 "GET / HTTP/1.1\r\n"
6472 "Host: www.example.org\r\n"
6473 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546474 };
6475
6476 MockRead data_reads1[] = {
6477 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6478 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6479 MockRead("Content-Length: 10\r\n\r\n"),
6480 MockRead(SYNCHRONOUS, ERR_FAILED),
6481 };
6482
6483 // After the challenge above, the transaction will be restarted using the
6484 // identity supplied by the user, not the one in the URL, to answer the
6485 // challenge.
6486 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236487 MockWrite(
6488 "GET / HTTP/1.1\r\n"
6489 "Host: www.example.org\r\n"
6490 "Connection: keep-alive\r\n"
6491 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546492 };
6493
6494 MockRead data_reads3[] = {
6495 MockRead("HTTP/1.0 200 OK\r\n"),
6496 MockRead("Content-Length: 100\r\n\r\n"),
6497 MockRead(SYNCHRONOUS, OK),
6498 };
6499
6500 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6501 data_writes1, arraysize(data_writes1));
6502 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6503 data_writes3, arraysize(data_writes3));
6504 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6505 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6506
6507 TestCompletionCallback callback1;
6508 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6509 EXPECT_EQ(ERR_IO_PENDING, rv);
6510 rv = callback1.WaitForResult();
6511 EXPECT_EQ(OK, rv);
6512 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6513
6514 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526515 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:546516 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6517
6518 TestCompletionCallback callback3;
6519 rv = trans->RestartWithAuth(
6520 AuthCredentials(kFoo, kBar), callback3.callback());
6521 EXPECT_EQ(ERR_IO_PENDING, rv);
6522 rv = callback3.WaitForResult();
6523 EXPECT_EQ(OK, rv);
6524 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6525
6526 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526527 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:546528
6529 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526530 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:546531 EXPECT_EQ(100, response->headers->GetContentLength());
6532
6533 // Empty the current queue.
6534 base::MessageLoop::current()->RunUntilIdle();
6535}
6536
[email protected]f9ee6b52008-11-08 06:46:236537// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:026538TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:096539 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:236540
6541 // Transaction 1: authenticate (foo, bar) on MyRealm1
6542 {
[email protected]1c773ea12009-04-28 19:58:426543 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236544 request.method = "GET";
bncce36dca22015-04-21 22:11:236545 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:236546 request.load_flags = 0;
6547
danakj1fd259a02016-04-16 03:17:096548 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506549 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276550
[email protected]f9ee6b52008-11-08 06:46:236551 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236552 MockWrite(
6553 "GET /x/y/z HTTP/1.1\r\n"
6554 "Host: www.example.org\r\n"
6555 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236556 };
6557
6558 MockRead data_reads1[] = {
6559 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6560 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6561 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066562 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236563 };
6564
6565 // Resend with authorization (username=foo, password=bar)
6566 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236567 MockWrite(
6568 "GET /x/y/z HTTP/1.1\r\n"
6569 "Host: www.example.org\r\n"
6570 "Connection: keep-alive\r\n"
6571 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236572 };
6573
6574 // Sever accepts the authorization.
6575 MockRead data_reads2[] = {
6576 MockRead("HTTP/1.0 200 OK\r\n"),
6577 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066578 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236579 };
6580
[email protected]31a2bfe2010-02-09 08:03:396581 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6582 data_writes1, arraysize(data_writes1));
6583 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6584 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076585 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6586 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236587
[email protected]49639fa2011-12-20 23:22:416588 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236589
[email protected]49639fa2011-12-20 23:22:416590 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426591 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236592
6593 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426594 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236595
[email protected]1c773ea12009-04-28 19:58:426596 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526597 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046598 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236599
[email protected]49639fa2011-12-20 23:22:416600 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236601
[email protected]49639fa2011-12-20 23:22:416602 rv = trans->RestartWithAuth(
6603 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426604 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236605
6606 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426607 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236608
6609 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526610 ASSERT_TRUE(response);
6611 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:236612 EXPECT_EQ(100, response->headers->GetContentLength());
6613 }
6614
6615 // ------------------------------------------------------------------------
6616
6617 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
6618 {
[email protected]1c773ea12009-04-28 19:58:426619 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236620 request.method = "GET";
6621 // Note that Transaction 1 was at /x/y/z, so this is in the same
6622 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:236623 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:236624 request.load_flags = 0;
6625
danakj1fd259a02016-04-16 03:17:096626 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506627 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276628
[email protected]f9ee6b52008-11-08 06:46:236629 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236630 MockWrite(
6631 "GET /x/y/a/b HTTP/1.1\r\n"
6632 "Host: www.example.org\r\n"
6633 "Connection: keep-alive\r\n"
6634 // Send preemptive authorization for MyRealm1
6635 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236636 };
6637
6638 // The server didn't like the preemptive authorization, and
6639 // challenges us for a different realm (MyRealm2).
6640 MockRead data_reads1[] = {
6641 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6642 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
6643 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066644 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236645 };
6646
6647 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
6648 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236649 MockWrite(
6650 "GET /x/y/a/b HTTP/1.1\r\n"
6651 "Host: www.example.org\r\n"
6652 "Connection: keep-alive\r\n"
6653 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236654 };
6655
6656 // Sever accepts the authorization.
6657 MockRead data_reads2[] = {
6658 MockRead("HTTP/1.0 200 OK\r\n"),
6659 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066660 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236661 };
6662
[email protected]31a2bfe2010-02-09 08:03:396663 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6664 data_writes1, arraysize(data_writes1));
6665 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6666 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076667 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6668 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236669
[email protected]49639fa2011-12-20 23:22:416670 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236671
[email protected]49639fa2011-12-20 23:22:416672 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426673 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236674
6675 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426676 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236677
[email protected]1c773ea12009-04-28 19:58:426678 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526679 ASSERT_TRUE(response);
6680 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:046681 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:236682 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:046683 response->auth_challenge->challenger.ToString());
6684 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:196685 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:236686
[email protected]49639fa2011-12-20 23:22:416687 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236688
[email protected]49639fa2011-12-20 23:22:416689 rv = trans->RestartWithAuth(
6690 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426691 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236692
6693 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426694 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236695
6696 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526697 ASSERT_TRUE(response);
6698 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:236699 EXPECT_EQ(100, response->headers->GetContentLength());
6700 }
6701
6702 // ------------------------------------------------------------------------
6703
6704 // Transaction 3: Resend a request in MyRealm's protection space --
6705 // succeed with preemptive authorization.
6706 {
[email protected]1c773ea12009-04-28 19:58:426707 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236708 request.method = "GET";
bncce36dca22015-04-21 22:11:236709 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:236710 request.load_flags = 0;
6711
danakj1fd259a02016-04-16 03:17:096712 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506713 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276714
[email protected]f9ee6b52008-11-08 06:46:236715 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236716 MockWrite(
6717 "GET /x/y/z2 HTTP/1.1\r\n"
6718 "Host: www.example.org\r\n"
6719 "Connection: keep-alive\r\n"
6720 // The authorization for MyRealm1 gets sent preemptively
6721 // (since the url is in the same protection space)
6722 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236723 };
6724
6725 // Sever accepts the preemptive authorization
6726 MockRead data_reads1[] = {
6727 MockRead("HTTP/1.0 200 OK\r\n"),
6728 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066729 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236730 };
6731
[email protected]31a2bfe2010-02-09 08:03:396732 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6733 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076734 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:236735
[email protected]49639fa2011-12-20 23:22:416736 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236737
[email protected]49639fa2011-12-20 23:22:416738 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426739 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236740
6741 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426742 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236743
[email protected]1c773ea12009-04-28 19:58:426744 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526745 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:236746
wezca1070932016-05-26 20:30:526747 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:236748 EXPECT_EQ(100, response->headers->GetContentLength());
6749 }
6750
6751 // ------------------------------------------------------------------------
6752
6753 // Transaction 4: request another URL in MyRealm (however the
6754 // url is not known to belong to the protection space, so no pre-auth).
6755 {
[email protected]1c773ea12009-04-28 19:58:426756 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236757 request.method = "GET";
bncce36dca22015-04-21 22:11:236758 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:236759 request.load_flags = 0;
6760
danakj1fd259a02016-04-16 03:17:096761 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506762 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276763
[email protected]f9ee6b52008-11-08 06:46:236764 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236765 MockWrite(
6766 "GET /x/1 HTTP/1.1\r\n"
6767 "Host: www.example.org\r\n"
6768 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236769 };
6770
6771 MockRead data_reads1[] = {
6772 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6773 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6774 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066775 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236776 };
6777
6778 // Resend with authorization from MyRealm's cache.
6779 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236780 MockWrite(
6781 "GET /x/1 HTTP/1.1\r\n"
6782 "Host: www.example.org\r\n"
6783 "Connection: keep-alive\r\n"
6784 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236785 };
6786
6787 // Sever accepts the authorization.
6788 MockRead data_reads2[] = {
6789 MockRead("HTTP/1.0 200 OK\r\n"),
6790 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066791 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236792 };
6793
[email protected]31a2bfe2010-02-09 08:03:396794 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6795 data_writes1, arraysize(data_writes1));
6796 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6797 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076798 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6799 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236800
[email protected]49639fa2011-12-20 23:22:416801 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236802
[email protected]49639fa2011-12-20 23:22:416803 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426804 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236805
6806 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426807 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236808
[email protected]0757e7702009-03-27 04:00:226809 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416810 TestCompletionCallback callback2;
6811 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426812 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226813 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426814 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226815 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6816
[email protected]1c773ea12009-04-28 19:58:426817 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526818 ASSERT_TRUE(response);
6819 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:236820 EXPECT_EQ(100, response->headers->GetContentLength());
6821 }
6822
6823 // ------------------------------------------------------------------------
6824
6825 // Transaction 5: request a URL in MyRealm, but the server rejects the
6826 // cached identity. Should invalidate and re-prompt.
6827 {
[email protected]1c773ea12009-04-28 19:58:426828 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236829 request.method = "GET";
bncce36dca22015-04-21 22:11:236830 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:236831 request.load_flags = 0;
6832
danakj1fd259a02016-04-16 03:17:096833 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506834 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276835
[email protected]f9ee6b52008-11-08 06:46:236836 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236837 MockWrite(
6838 "GET /p/q/t HTTP/1.1\r\n"
6839 "Host: www.example.org\r\n"
6840 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236841 };
6842
6843 MockRead data_reads1[] = {
6844 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6845 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6846 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066847 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236848 };
6849
6850 // Resend with authorization from cache for MyRealm.
6851 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236852 MockWrite(
6853 "GET /p/q/t HTTP/1.1\r\n"
6854 "Host: www.example.org\r\n"
6855 "Connection: keep-alive\r\n"
6856 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236857 };
6858
6859 // Sever rejects the authorization.
6860 MockRead data_reads2[] = {
6861 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6862 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6863 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066864 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236865 };
6866
6867 // At this point we should prompt for new credentials for MyRealm.
6868 // Restart with username=foo3, password=foo4.
6869 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236870 MockWrite(
6871 "GET /p/q/t HTTP/1.1\r\n"
6872 "Host: www.example.org\r\n"
6873 "Connection: keep-alive\r\n"
6874 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236875 };
6876
6877 // Sever accepts the authorization.
6878 MockRead data_reads3[] = {
6879 MockRead("HTTP/1.0 200 OK\r\n"),
6880 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066881 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236882 };
6883
[email protected]31a2bfe2010-02-09 08:03:396884 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6885 data_writes1, arraysize(data_writes1));
6886 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6887 data_writes2, arraysize(data_writes2));
6888 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6889 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076890 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6891 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6892 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236893
[email protected]49639fa2011-12-20 23:22:416894 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236895
[email protected]49639fa2011-12-20 23:22:416896 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426897 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236898
6899 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426900 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236901
[email protected]0757e7702009-03-27 04:00:226902 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416903 TestCompletionCallback callback2;
6904 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426905 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226906 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426907 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226908 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6909
[email protected]1c773ea12009-04-28 19:58:426910 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526911 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046912 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236913
[email protected]49639fa2011-12-20 23:22:416914 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236915
[email protected]49639fa2011-12-20 23:22:416916 rv = trans->RestartWithAuth(
6917 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426918 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236919
[email protected]0757e7702009-03-27 04:00:226920 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426921 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236922
6923 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526924 ASSERT_TRUE(response);
6925 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:236926 EXPECT_EQ(100, response->headers->GetContentLength());
6927 }
6928}
[email protected]89ceba9a2009-03-21 03:46:066929
[email protected]3c32c5f2010-05-18 15:18:126930// Tests that nonce count increments when multiple auth attempts
6931// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026932TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446933 HttpAuthHandlerDigest::Factory* digest_factory =
6934 new HttpAuthHandlerDigest::Factory();
6935 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6936 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6937 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076938 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:096939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126940
6941 // Transaction 1: authenticate (foo, bar) on MyRealm1
6942 {
[email protected]3c32c5f2010-05-18 15:18:126943 HttpRequestInfo request;
6944 request.method = "GET";
bncce36dca22015-04-21 22:11:236945 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126946 request.load_flags = 0;
6947
danakj1fd259a02016-04-16 03:17:096948 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506949 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276950
[email protected]3c32c5f2010-05-18 15:18:126951 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236952 MockWrite(
6953 "GET /x/y/z HTTP/1.1\r\n"
6954 "Host: www.example.org\r\n"
6955 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126956 };
6957
6958 MockRead data_reads1[] = {
6959 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6960 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6961 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066962 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126963 };
6964
6965 // Resend with authorization (username=foo, password=bar)
6966 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236967 MockWrite(
6968 "GET /x/y/z HTTP/1.1\r\n"
6969 "Host: www.example.org\r\n"
6970 "Connection: keep-alive\r\n"
6971 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6972 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6973 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6974 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126975 };
6976
6977 // Sever accepts the authorization.
6978 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:086979 MockRead("HTTP/1.0 200 OK\r\n"),
6980 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126981 };
6982
6983 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6984 data_writes1, arraysize(data_writes1));
6985 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6986 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076987 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6988 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126989
[email protected]49639fa2011-12-20 23:22:416990 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126991
[email protected]49639fa2011-12-20 23:22:416992 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126993 EXPECT_EQ(ERR_IO_PENDING, rv);
6994
6995 rv = callback1.WaitForResult();
6996 EXPECT_EQ(OK, rv);
6997
6998 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526999 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047000 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127001
[email protected]49639fa2011-12-20 23:22:417002 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127003
[email protected]49639fa2011-12-20 23:22:417004 rv = trans->RestartWithAuth(
7005 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:127006 EXPECT_EQ(ERR_IO_PENDING, rv);
7007
7008 rv = callback2.WaitForResult();
7009 EXPECT_EQ(OK, rv);
7010
7011 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527012 ASSERT_TRUE(response);
7013 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127014 }
7015
7016 // ------------------------------------------------------------------------
7017
7018 // Transaction 2: Request another resource in digestive's protection space.
7019 // This will preemptively add an Authorization header which should have an
7020 // "nc" value of 2 (as compared to 1 in the first use.
7021 {
[email protected]3c32c5f2010-05-18 15:18:127022 HttpRequestInfo request;
7023 request.method = "GET";
7024 // Note that Transaction 1 was at /x/y/z, so this is in the same
7025 // protection space as digest.
bncce36dca22015-04-21 22:11:237026 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127027 request.load_flags = 0;
7028
danakj1fd259a02016-04-16 03:17:097029 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507030 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277031
[email protected]3c32c5f2010-05-18 15:18:127032 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237033 MockWrite(
7034 "GET /x/y/a/b HTTP/1.1\r\n"
7035 "Host: www.example.org\r\n"
7036 "Connection: keep-alive\r\n"
7037 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7038 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7039 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7040 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127041 };
7042
7043 // Sever accepts the authorization.
7044 MockRead data_reads1[] = {
7045 MockRead("HTTP/1.0 200 OK\r\n"),
7046 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067047 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127048 };
7049
7050 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7051 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077052 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127053
[email protected]49639fa2011-12-20 23:22:417054 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127055
[email protected]49639fa2011-12-20 23:22:417056 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:127057 EXPECT_EQ(ERR_IO_PENDING, rv);
7058
7059 rv = callback1.WaitForResult();
7060 EXPECT_EQ(OK, rv);
7061
7062 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527063 ASSERT_TRUE(response);
7064 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127065 }
7066}
7067
[email protected]89ceba9a2009-03-21 03:46:067068// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:027069TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067070 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097071 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7072 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:417073 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:067074
7075 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:067076 trans->read_buf_ = new IOBuffer(15);
7077 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:207078 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067079
7080 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:147081 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:577082 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087083 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577084 response->response_time = base::Time::Now();
7085 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067086
7087 { // Setup state for response_.vary_data
7088 HttpRequestInfo request;
7089 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7090 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277091 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437092 request.extra_headers.SetHeader("Foo", "1");
7093 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507094 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067095 }
7096
7097 // Cause the above state to be reset.
7098 trans->ResetStateForRestart();
7099
7100 // Verify that the state that needed to be reset, has been reset.
wezca1070932016-05-26 20:30:527101 EXPECT_FALSE(trans->read_buf_);
[email protected]89ceba9a2009-03-21 03:46:067102 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:207103 EXPECT_TRUE(trans->request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527104 EXPECT_FALSE(response->auth_challenge);
7105 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047106 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087107 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577108 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067109}
7110
[email protected]bacff652009-03-31 17:50:337111// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:027112TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337113 HttpRequestInfo request;
7114 request.method = "GET";
bncce36dca22015-04-21 22:11:237115 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337116 request.load_flags = 0;
7117
danakj1fd259a02016-04-16 03:17:097118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7119 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277121
[email protected]bacff652009-03-31 17:50:337122 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237123 MockWrite(
7124 "GET / HTTP/1.1\r\n"
7125 "Host: www.example.org\r\n"
7126 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337127 };
7128
7129 MockRead data_reads[] = {
7130 MockRead("HTTP/1.0 200 OK\r\n"),
7131 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7132 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067133 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337134 };
7135
[email protected]5ecc992a42009-11-11 01:41:597136 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397137 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7138 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067139 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7140 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337141
[email protected]bb88e1d32013-05-03 23:11:077142 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7143 session_deps_.socket_factory->AddSocketDataProvider(&data);
7144 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7145 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337146
[email protected]49639fa2011-12-20 23:22:417147 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337148
[email protected]49639fa2011-12-20 23:22:417149 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337150 EXPECT_EQ(ERR_IO_PENDING, rv);
7151
7152 rv = callback.WaitForResult();
7153 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7154
[email protected]49639fa2011-12-20 23:22:417155 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337156 EXPECT_EQ(ERR_IO_PENDING, rv);
7157
7158 rv = callback.WaitForResult();
7159 EXPECT_EQ(OK, rv);
7160
7161 const HttpResponseInfo* response = trans->GetResponseInfo();
7162
wezca1070932016-05-26 20:30:527163 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337164 EXPECT_EQ(100, response->headers->GetContentLength());
7165}
7166
7167// Test HTTPS connections to a site with a bad certificate, going through a
7168// proxy
[email protected]23e482282013-06-14 16:08:027169TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037170 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337171
7172 HttpRequestInfo request;
7173 request.method = "GET";
bncce36dca22015-04-21 22:11:237174 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337175 request.load_flags = 0;
7176
7177 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177178 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7179 "Host: www.example.org:443\r\n"
7180 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337181 };
7182
7183 MockRead proxy_reads[] = {
7184 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067185 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337186 };
7187
7188 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177189 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7190 "Host: www.example.org:443\r\n"
7191 "Proxy-Connection: keep-alive\r\n\r\n"),
7192 MockWrite("GET / HTTP/1.1\r\n"
7193 "Host: www.example.org\r\n"
7194 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337195 };
7196
7197 MockRead data_reads[] = {
7198 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7199 MockRead("HTTP/1.0 200 OK\r\n"),
7200 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7201 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067202 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337203 };
7204
[email protected]31a2bfe2010-02-09 08:03:397205 StaticSocketDataProvider ssl_bad_certificate(
7206 proxy_reads, arraysize(proxy_reads),
7207 proxy_writes, arraysize(proxy_writes));
7208 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7209 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067210 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7211 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337212
[email protected]bb88e1d32013-05-03 23:11:077213 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7214 session_deps_.socket_factory->AddSocketDataProvider(&data);
7215 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7216 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337217
[email protected]49639fa2011-12-20 23:22:417218 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337219
7220 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077221 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337222
danakj1fd259a02016-04-16 03:17:097223 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7224 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417225 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:337226
[email protected]49639fa2011-12-20 23:22:417227 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337228 EXPECT_EQ(ERR_IO_PENDING, rv);
7229
7230 rv = callback.WaitForResult();
7231 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7232
[email protected]49639fa2011-12-20 23:22:417233 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337234 EXPECT_EQ(ERR_IO_PENDING, rv);
7235
7236 rv = callback.WaitForResult();
7237 EXPECT_EQ(OK, rv);
7238
7239 const HttpResponseInfo* response = trans->GetResponseInfo();
7240
wezca1070932016-05-26 20:30:527241 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337242 EXPECT_EQ(100, response->headers->GetContentLength());
7243 }
7244}
7245
[email protected]2df19bb2010-08-25 20:13:467246
7247// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:027248TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037249 session_deps_.proxy_service =
7250 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517251 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077252 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467253
7254 HttpRequestInfo request;
7255 request.method = "GET";
bncce36dca22015-04-21 22:11:237256 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467257 request.load_flags = 0;
7258
7259 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177260 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7261 "Host: www.example.org:443\r\n"
7262 "Proxy-Connection: keep-alive\r\n\r\n"),
7263 MockWrite("GET / HTTP/1.1\r\n"
7264 "Host: www.example.org\r\n"
7265 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467266 };
7267
7268 MockRead data_reads[] = {
7269 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7270 MockRead("HTTP/1.1 200 OK\r\n"),
7271 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7272 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067273 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467274 };
7275
7276 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7277 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067278 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7279 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467280
[email protected]bb88e1d32013-05-03 23:11:077281 session_deps_.socket_factory->AddSocketDataProvider(&data);
7282 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7283 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467284
[email protected]49639fa2011-12-20 23:22:417285 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467286
danakj1fd259a02016-04-16 03:17:097287 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7288 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417289 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467290
[email protected]49639fa2011-12-20 23:22:417291 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467292 EXPECT_EQ(ERR_IO_PENDING, rv);
7293
7294 rv = callback.WaitForResult();
7295 EXPECT_EQ(OK, rv);
7296 const HttpResponseInfo* response = trans->GetResponseInfo();
7297
wezca1070932016-05-26 20:30:527298 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467299
7300 EXPECT_TRUE(response->headers->IsKeepAlive());
7301 EXPECT_EQ(200, response->headers->response_code());
7302 EXPECT_EQ(100, response->headers->GetContentLength());
7303 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207304
7305 LoadTimingInfo load_timing_info;
7306 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7307 TestLoadTimingNotReusedWithPac(load_timing_info,
7308 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467309}
7310
[email protected]511f6f52010-12-17 03:58:297311// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027312TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037313 session_deps_.proxy_service =
7314 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517315 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077316 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297317
7318 HttpRequestInfo request;
7319 request.method = "GET";
bncce36dca22015-04-21 22:11:237320 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297321 request.load_flags = 0;
7322
7323 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177324 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7325 "Host: www.example.org:443\r\n"
7326 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297327 };
7328
7329 MockRead data_reads[] = {
7330 MockRead("HTTP/1.1 302 Redirect\r\n"),
7331 MockRead("Location: http://login.example.com/\r\n"),
7332 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067333 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297334 };
7335
7336 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7337 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067338 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297339
[email protected]bb88e1d32013-05-03 23:11:077340 session_deps_.socket_factory->AddSocketDataProvider(&data);
7341 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297342
[email protected]49639fa2011-12-20 23:22:417343 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297344
danakj1fd259a02016-04-16 03:17:097345 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7346 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417347 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297348
[email protected]49639fa2011-12-20 23:22:417349 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297350 EXPECT_EQ(ERR_IO_PENDING, rv);
7351
7352 rv = callback.WaitForResult();
7353 EXPECT_EQ(OK, rv);
7354 const HttpResponseInfo* response = trans->GetResponseInfo();
7355
wezca1070932016-05-26 20:30:527356 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297357
7358 EXPECT_EQ(302, response->headers->response_code());
7359 std::string url;
7360 EXPECT_TRUE(response->headers->IsRedirect(&url));
7361 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207362
7363 // In the case of redirects from proxies, HttpNetworkTransaction returns
7364 // timing for the proxy connection instead of the connection to the host,
7365 // and no send / receive times.
7366 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7367 LoadTimingInfo load_timing_info;
7368 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7369
7370 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:297371 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207372
7373 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7374 EXPECT_LE(load_timing_info.proxy_resolve_start,
7375 load_timing_info.proxy_resolve_end);
7376 EXPECT_LE(load_timing_info.proxy_resolve_end,
7377 load_timing_info.connect_timing.connect_start);
7378 ExpectConnectTimingHasTimes(
7379 load_timing_info.connect_timing,
7380 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7381
7382 EXPECT_TRUE(load_timing_info.send_start.is_null());
7383 EXPECT_TRUE(load_timing_info.send_end.is_null());
7384 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297385}
7386
7387// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027388TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037389 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297390
7391 HttpRequestInfo request;
7392 request.method = "GET";
bncce36dca22015-04-21 22:11:237393 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297394 request.load_flags = 0;
7395
danakj1fd259a02016-04-16 03:17:097396 std::unique_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237397 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097398 std::unique_ptr<SpdySerializedFrame> goaway(
[email protected]c10b20852013-05-15 21:29:207399 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297400 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137401 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
7402 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297403 };
7404
7405 static const char* const kExtraHeaders[] = {
7406 "location",
7407 "http://login.example.com/",
7408 };
danakj1fd259a02016-04-16 03:17:097409 std::unique_ptr<SpdySerializedFrame> resp(
7410 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
7411 arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297412 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137413 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297414 };
7415
rch8e6c6c42015-05-01 14:05:137416 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7417 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067418 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387419 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297420
[email protected]bb88e1d32013-05-03 23:11:077421 session_deps_.socket_factory->AddSocketDataProvider(&data);
7422 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297423
[email protected]49639fa2011-12-20 23:22:417424 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297425
danakj1fd259a02016-04-16 03:17:097426 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7427 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417428 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297429
[email protected]49639fa2011-12-20 23:22:417430 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297431 EXPECT_EQ(ERR_IO_PENDING, rv);
7432
7433 rv = callback.WaitForResult();
7434 EXPECT_EQ(OK, rv);
7435 const HttpResponseInfo* response = trans->GetResponseInfo();
7436
wezca1070932016-05-26 20:30:527437 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297438
7439 EXPECT_EQ(302, response->headers->response_code());
7440 std::string url;
7441 EXPECT_TRUE(response->headers->IsRedirect(&url));
7442 EXPECT_EQ("http://login.example.com/", url);
7443}
7444
[email protected]4eddbc732012-08-09 05:40:177445// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027446TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177447 ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037448 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297449
7450 HttpRequestInfo request;
7451 request.method = "GET";
bncce36dca22015-04-21 22:11:237452 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297453 request.load_flags = 0;
7454
7455 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177456 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7457 "Host: www.example.org:443\r\n"
7458 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297459 };
7460
7461 MockRead data_reads[] = {
7462 MockRead("HTTP/1.1 404 Not Found\r\n"),
7463 MockRead("Content-Length: 23\r\n\r\n"),
7464 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067465 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297466 };
7467
7468 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7469 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067470 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297471
[email protected]bb88e1d32013-05-03 23:11:077472 session_deps_.socket_factory->AddSocketDataProvider(&data);
7473 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297474
[email protected]49639fa2011-12-20 23:22:417475 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297476
danakj1fd259a02016-04-16 03:17:097477 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7478 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417479 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297480
[email protected]49639fa2011-12-20 23:22:417481 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297482 EXPECT_EQ(ERR_IO_PENDING, rv);
7483
7484 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177485 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297486
ttuttle960fcbf2016-04-19 13:26:327487 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297488}
7489
[email protected]4eddbc732012-08-09 05:40:177490// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027491TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177492 ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037493 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297494
7495 HttpRequestInfo request;
7496 request.method = "GET";
bncce36dca22015-04-21 22:11:237497 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297498 request.load_flags = 0;
7499
danakj1fd259a02016-04-16 03:17:097500 std::unique_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237501 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097502 std::unique_ptr<SpdySerializedFrame> rst(
[email protected]c10b20852013-05-15 21:29:207503 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297504 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137505 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:297506 };
7507
7508 static const char* const kExtraHeaders[] = {
7509 "location",
7510 "http://login.example.com/",
7511 };
danakj1fd259a02016-04-16 03:17:097512 std::unique_ptr<SpdySerializedFrame> resp(
7513 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
7514 arraysize(kExtraHeaders) / 2, 1));
7515 std::unique_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame(
bncb03b1092016-04-06 11:19:557516 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297517 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137518 CreateMockRead(*resp.get(), 1),
7519 CreateMockRead(*body.get(), 2),
7520 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297521 };
7522
rch8e6c6c42015-05-01 14:05:137523 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7524 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067525 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387526 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297527
[email protected]bb88e1d32013-05-03 23:11:077528 session_deps_.socket_factory->AddSocketDataProvider(&data);
7529 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297530
[email protected]49639fa2011-12-20 23:22:417531 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297532
danakj1fd259a02016-04-16 03:17:097533 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7534 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417535 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297536
[email protected]49639fa2011-12-20 23:22:417537 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297538 EXPECT_EQ(ERR_IO_PENDING, rv);
7539
7540 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177541 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297542
ttuttle960fcbf2016-04-19 13:26:327543 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297544}
7545
[email protected]0c5fb722012-02-28 11:50:357546// Test the request-challenge-retry sequence for basic auth, through
7547// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:027548TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:357549 HttpRequestInfo request;
7550 request.method = "GET";
bncce36dca22015-04-21 22:11:237551 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:357552 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:297553 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:357554
7555 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037556 session_deps_.proxy_service =
7557 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517558 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077559 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:097560 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:357561
7562 // Since we have proxy, should try to establish tunnel.
danakj1fd259a02016-04-16 03:17:097563 std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237564 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097565 std::unique_ptr<SpdySerializedFrame> rst(
[email protected]c10b20852013-05-15 21:29:207566 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
rdsmithebb50aa2015-11-12 03:44:387567 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:357568
7569 // After calling trans->RestartWithAuth(), this is the request we should
7570 // be issuing -- the final header line contains the credentials.
7571 const char* const kAuthCredentials[] = {
7572 "proxy-authorization", "Basic Zm9vOmJhcg==",
7573 };
danakj1fd259a02016-04-16 03:17:097574 std::unique_ptr<SpdySerializedFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:347575 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:237576 HostPortPair("www.example.org", 443)));
7577 // fetch https://www.example.org/ via HTTP
7578 const char get[] =
7579 "GET / HTTP/1.1\r\n"
7580 "Host: www.example.org\r\n"
7581 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:097582 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:027583 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:357584
7585 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137586 CreateMockWrite(*req, 0, ASYNC),
7587 CreateMockWrite(*rst, 2, ASYNC),
7588 CreateMockWrite(*connect2, 3),
7589 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:357590 };
7591
7592 // The proxy responds to the connect with a 407, using a persistent
7593 // connection.
thestig9d3bb0c2015-01-24 00:49:517594 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:357595 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:357596 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
7597 };
danakj1fd259a02016-04-16 03:17:097598 std::unique_ptr<SpdySerializedFrame> conn_auth_resp(
bncb03b1092016-04-06 11:19:557599 spdy_util_.ConstructSpdySynReplyError(kAuthStatus, kAuthChallenge,
7600 arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:357601
danakj1fd259a02016-04-16 03:17:097602 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:027603 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:357604 const char resp[] = "HTTP/1.1 200 OK\r\n"
7605 "Content-Length: 5\r\n\r\n";
7606
danakj1fd259a02016-04-16 03:17:097607 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:027608 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
danakj1fd259a02016-04-16 03:17:097609 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:027610 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:357611 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137612 CreateMockRead(*conn_auth_resp, 1, ASYNC),
7613 CreateMockRead(*conn_resp, 4, ASYNC),
7614 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
7615 CreateMockRead(*wrapped_body, 7, ASYNC),
7616 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:357617 };
7618
rch8e6c6c42015-05-01 14:05:137619 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7620 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077621 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:357622 // Negotiate SPDY to the proxy
7623 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387624 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077625 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:357626 // Vanilla SSL to the server
7627 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077628 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:357629
7630 TestCompletionCallback callback1;
7631
danakj1fd259a02016-04-16 03:17:097632 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507633 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:357634
7635 int rv = trans->Start(&request, callback1.callback(), log.bound());
7636 EXPECT_EQ(ERR_IO_PENDING, rv);
7637
7638 rv = callback1.WaitForResult();
7639 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:467640 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:357641 log.GetEntries(&entries);
7642 size_t pos = ExpectLogContainsSomewhere(
7643 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
7644 NetLog::PHASE_NONE);
7645 ExpectLogContainsSomewhere(
7646 entries, pos,
7647 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
7648 NetLog::PHASE_NONE);
7649
7650 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527651 ASSERT_TRUE(response);
7652 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:357653 EXPECT_EQ(407, response->headers->response_code());
7654 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:527655 EXPECT_TRUE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:357656 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
7657
7658 TestCompletionCallback callback2;
7659
7660 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
7661 callback2.callback());
7662 EXPECT_EQ(ERR_IO_PENDING, rv);
7663
7664 rv = callback2.WaitForResult();
7665 EXPECT_EQ(OK, rv);
7666
7667 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527668 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:357669
7670 EXPECT_TRUE(response->headers->IsKeepAlive());
7671 EXPECT_EQ(200, response->headers->response_code());
7672 EXPECT_EQ(5, response->headers->GetContentLength());
7673 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7674
7675 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:527676 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:357677
[email protected]029c83b62013-01-24 05:28:207678 LoadTimingInfo load_timing_info;
7679 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7680 TestLoadTimingNotReusedWithPac(load_timing_info,
7681 CONNECT_TIMING_HAS_SSL_TIMES);
7682
[email protected]0c5fb722012-02-28 11:50:357683 trans.reset();
7684 session->CloseAllConnections();
7685}
7686
[email protected]7c6f7ba2012-04-03 04:09:297687// Test that an explicitly trusted SPDY proxy can push a resource from an
7688// origin that is different from that of its associated resource.
tbansal28e68f82016-02-04 02:56:157689TEST_P(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
7690 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:097691 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:157692 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
7693 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:297694 HttpRequestInfo request;
7695 HttpRequestInfo push_request;
7696
[email protected]7c6f7ba2012-04-03 04:09:297697 request.method = "GET";
bncce36dca22015-04-21 22:11:237698 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:297699 push_request.method = "GET";
7700 push_request.url = GURL("http://www.another-origin.com/foo.dat");
7701
tbansal28e68f82016-02-04 02:56:157702 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:037703 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:157704 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:517705 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077706 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507707
tbansal28e68f82016-02-04 02:56:157708 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:507709
danakj1fd259a02016-04-16 03:17:097710 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:297711
danakj1fd259a02016-04-16 03:17:097712 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:497713 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:297714
7715 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137716 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:297717 };
7718
danakj1fd259a02016-04-16 03:17:097719 std::unique_ptr<SpdySerializedFrame> stream1_reply(
bncb03b1092016-04-06 11:19:557720 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:297721
danakj1fd259a02016-04-16 03:17:097722 std::unique_ptr<SpdySerializedFrame> stream1_body(
bncb03b1092016-04-06 11:19:557723 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:297724
danakj1fd259a02016-04-16 03:17:097725 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:557726 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:437727 const char kPushedData[] = "pushed";
danakj1fd259a02016-04-16 03:17:097728 std::unique_ptr<SpdySerializedFrame> stream2_body(
bncb03b1092016-04-06 11:19:557729 spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
7730 true));
[email protected]7c6f7ba2012-04-03 04:09:297731
7732 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137733 CreateMockRead(*stream1_reply, 1, ASYNC),
7734 CreateMockRead(*stream2_syn, 2, ASYNC),
7735 CreateMockRead(*stream1_body, 3, ASYNC),
7736 CreateMockRead(*stream2_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:597737 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:297738 };
7739
rch8e6c6c42015-05-01 14:05:137740 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7741 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077742 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:297743 // Negotiate SPDY to the proxy
7744 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387745 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077746 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:297747
danakj1fd259a02016-04-16 03:17:097748 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507749 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:297750 TestCompletionCallback callback;
7751 int rv = trans->Start(&request, callback.callback(), log.bound());
7752 EXPECT_EQ(ERR_IO_PENDING, rv);
7753
7754 rv = callback.WaitForResult();
7755 EXPECT_EQ(OK, rv);
7756 const HttpResponseInfo* response = trans->GetResponseInfo();
7757
danakj1fd259a02016-04-16 03:17:097758 std::unique_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:507759 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7760 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:297761 EXPECT_EQ(ERR_IO_PENDING, rv);
7762
7763 rv = callback.WaitForResult();
7764 EXPECT_EQ(OK, rv);
7765 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
7766
wezca1070932016-05-26 20:30:527767 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:297768 EXPECT_TRUE(response->headers->IsKeepAlive());
7769
7770 EXPECT_EQ(200, response->headers->response_code());
7771 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7772
7773 std::string response_data;
7774 rv = ReadTransaction(trans.get(), &response_data);
7775 EXPECT_EQ(OK, rv);
7776 EXPECT_EQ("hello!", response_data);
7777
[email protected]029c83b62013-01-24 05:28:207778 LoadTimingInfo load_timing_info;
7779 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7780 TestLoadTimingNotReusedWithPac(load_timing_info,
7781 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7782
[email protected]7c6f7ba2012-04-03 04:09:297783 // Verify the pushed stream.
wezca1070932016-05-26 20:30:527784 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:297785 EXPECT_EQ(200, push_response->headers->response_code());
7786
7787 rv = ReadTransaction(push_trans.get(), &response_data);
7788 EXPECT_EQ(OK, rv);
7789 EXPECT_EQ("pushed", response_data);
7790
[email protected]029c83b62013-01-24 05:28:207791 LoadTimingInfo push_load_timing_info;
7792 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
7793 TestLoadTimingReusedWithPac(push_load_timing_info);
7794 // The transactions should share a socket ID, despite being for different
7795 // origins.
7796 EXPECT_EQ(load_timing_info.socket_log_id,
7797 push_load_timing_info.socket_log_id);
7798
[email protected]7c6f7ba2012-04-03 04:09:297799 trans.reset();
7800 push_trans.reset();
7801 session->CloseAllConnections();
7802}
7803
[email protected]8c843192012-04-05 07:15:007804// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:027805TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:157806 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:097807 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:157808 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
7809 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:007810 HttpRequestInfo request;
7811
7812 request.method = "GET";
bncce36dca22015-04-21 22:11:237813 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:007814
tbansal28e68f82016-02-04 02:56:157815 session_deps_.proxy_service =
7816 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:517817 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077818 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507819
7820 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:157821 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:507822
danakj1fd259a02016-04-16 03:17:097823 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:007824
danakj1fd259a02016-04-16 03:17:097825 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:497826 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:007827
danakj1fd259a02016-04-16 03:17:097828 std::unique_ptr<SpdySerializedFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207829 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007830
7831 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137832 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007833 };
7834
danakj1fd259a02016-04-16 03:17:097835 std::unique_ptr<SpdySerializedFrame> stream1_reply(
bncb03b1092016-04-06 11:19:557836 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007837
danakj1fd259a02016-04-16 03:17:097838 std::unique_ptr<SpdySerializedFrame> stream1_body(
bncb03b1092016-04-06 11:19:557839 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007840
danakj1fd259a02016-04-16 03:17:097841 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:557842 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:007843
7844 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137845 CreateMockRead(*stream1_reply, 1, ASYNC),
7846 CreateMockRead(*stream2_syn, 2, ASYNC),
7847 CreateMockRead(*stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:597848 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:007849 };
7850
rch8e6c6c42015-05-01 14:05:137851 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7852 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077853 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007854 // Negotiate SPDY to the proxy
7855 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387856 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077857 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007858
danakj1fd259a02016-04-16 03:17:097859 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507860 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007861 TestCompletionCallback callback;
7862 int rv = trans->Start(&request, callback.callback(), log.bound());
7863 EXPECT_EQ(ERR_IO_PENDING, rv);
7864
7865 rv = callback.WaitForResult();
7866 EXPECT_EQ(OK, rv);
7867 const HttpResponseInfo* response = trans->GetResponseInfo();
7868
wezca1070932016-05-26 20:30:527869 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:007870 EXPECT_TRUE(response->headers->IsKeepAlive());
7871
7872 EXPECT_EQ(200, response->headers->response_code());
7873 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7874
7875 std::string response_data;
7876 rv = ReadTransaction(trans.get(), &response_data);
7877 EXPECT_EQ(OK, rv);
7878 EXPECT_EQ("hello!", response_data);
7879
7880 trans.reset();
7881 session->CloseAllConnections();
7882}
7883
tbansal8ef1d3e2016-02-03 04:05:427884// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
7885// resources.
7886TEST_P(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:157887 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:097888 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:157889 proxy_delegate->set_trusted_spdy_proxy(
7890 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
7891
tbansal8ef1d3e2016-02-03 04:05:427892 HttpRequestInfo request;
7893
7894 request.method = "GET";
7895 request.url = GURL("http://www.example.org/");
7896
7897 // Configure against https proxy server "myproxy:70".
7898 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
7899 BoundTestNetLog log;
7900 session_deps_.net_log = log.bound().net_log();
7901
7902 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:157903 session_deps_.proxy_delegate.reset(proxy_delegate.release());
tbansal8ef1d3e2016-02-03 04:05:427904
danakj1fd259a02016-04-16 03:17:097905 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:427906
danakj1fd259a02016-04-16 03:17:097907 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:497908 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
tbansal8ef1d3e2016-02-03 04:05:427909
7910 MockWrite spdy_writes[] = {
7911 CreateMockWrite(*stream1_syn, 0, ASYNC),
7912 };
7913
danakj1fd259a02016-04-16 03:17:097914 std::unique_ptr<SpdySerializedFrame> stream1_reply(
tbansal8ef1d3e2016-02-03 04:05:427915 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
7916
danakj1fd259a02016-04-16 03:17:097917 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:497918 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
7919
danakj1fd259a02016-04-16 03:17:097920 std::unique_ptr<SpdySerializedFrame> stream1_body(
tbansal8ef1d3e2016-02-03 04:05:427921 spdy_util_.ConstructSpdyBodyFrame(1, true));
7922
danakj1fd259a02016-04-16 03:17:097923 std::unique_ptr<SpdySerializedFrame> stream2_reply(
tbansal8ef1d3e2016-02-03 04:05:427924 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
7925
danakj1fd259a02016-04-16 03:17:097926 std::unique_ptr<SpdySerializedFrame> stream2_body(
tbansal8ef1d3e2016-02-03 04:05:427927 spdy_util_.ConstructSpdyBodyFrame(1, true));
7928
7929 MockRead spdy_reads[] = {
7930 CreateMockRead(*stream1_reply, 1, ASYNC),
7931 CreateMockRead(*stream2_syn, 2, ASYNC),
7932 CreateMockRead(*stream1_body, 3, ASYNC),
7933 CreateMockRead(*stream2_body, 4, ASYNC),
7934 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
7935 };
7936
7937 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7938 arraysize(spdy_writes));
7939 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7940 // Negotiate SPDY to the proxy
7941 SSLSocketDataProvider proxy(ASYNC, OK);
7942 proxy.SetNextProto(GetProtocol());
7943 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
7944
danakj1fd259a02016-04-16 03:17:097945 std::unique_ptr<HttpTransaction> trans(
tbansal8ef1d3e2016-02-03 04:05:427946 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7947 TestCompletionCallback callback;
7948 int rv = trans->Start(&request, callback.callback(), log.bound());
7949 EXPECT_EQ(ERR_IO_PENDING, rv);
7950
7951 rv = callback.WaitForResult();
7952 EXPECT_EQ(OK, rv);
7953 const HttpResponseInfo* response = trans->GetResponseInfo();
7954
wezca1070932016-05-26 20:30:527955 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:427956 EXPECT_TRUE(response->headers->IsKeepAlive());
7957
7958 EXPECT_EQ(200, response->headers->response_code());
7959 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7960
7961 std::string response_data;
7962 rv = ReadTransaction(trans.get(), &response_data);
7963 EXPECT_EQ(OK, rv);
7964 EXPECT_EQ("hello!", response_data);
7965
7966 trans.reset();
7967 session->CloseAllConnections();
7968}
7969
[email protected]2df19bb2010-08-25 20:13:467970// Test HTTPS connections to a site with a bad certificate, going through an
7971// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027972TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037973 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:467974
7975 HttpRequestInfo request;
7976 request.method = "GET";
bncce36dca22015-04-21 22:11:237977 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467978 request.load_flags = 0;
7979
7980 // Attempt to fetch the URL from a server with a bad cert
7981 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:177982 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7983 "Host: www.example.org:443\r\n"
7984 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467985 };
7986
7987 MockRead bad_cert_reads[] = {
7988 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067989 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467990 };
7991
7992 // Attempt to fetch the URL with a good cert
7993 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177994 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7995 "Host: www.example.org:443\r\n"
7996 "Proxy-Connection: keep-alive\r\n\r\n"),
7997 MockWrite("GET / HTTP/1.1\r\n"
7998 "Host: www.example.org\r\n"
7999 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468000 };
8001
8002 MockRead good_cert_reads[] = {
8003 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8004 MockRead("HTTP/1.0 200 OK\r\n"),
8005 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8006 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068007 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468008 };
8009
8010 StaticSocketDataProvider ssl_bad_certificate(
8011 bad_cert_reads, arraysize(bad_cert_reads),
8012 bad_cert_writes, arraysize(bad_cert_writes));
8013 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8014 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068015 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8016 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468017
8018 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078019 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8020 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8021 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468022
8023 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078024 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8025 session_deps_.socket_factory->AddSocketDataProvider(&data);
8026 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468027
[email protected]49639fa2011-12-20 23:22:418028 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468029
danakj1fd259a02016-04-16 03:17:098030 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8031 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418032 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:468033
[email protected]49639fa2011-12-20 23:22:418034 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:468035 EXPECT_EQ(ERR_IO_PENDING, rv);
8036
8037 rv = callback.WaitForResult();
8038 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
8039
[email protected]49639fa2011-12-20 23:22:418040 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:468041 EXPECT_EQ(ERR_IO_PENDING, rv);
8042
8043 rv = callback.WaitForResult();
8044 EXPECT_EQ(OK, rv);
8045
8046 const HttpResponseInfo* response = trans->GetResponseInfo();
8047
wezca1070932016-05-26 20:30:528048 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468049 EXPECT_EQ(100, response->headers->GetContentLength());
8050}
8051
[email protected]23e482282013-06-14 16:08:028052TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428053 HttpRequestInfo request;
8054 request.method = "GET";
bncce36dca22015-04-21 22:11:238055 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438056 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8057 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428058
danakj1fd259a02016-04-16 03:17:098059 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8060 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418061 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278062
[email protected]1c773ea12009-04-28 19:58:428063 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238064 MockWrite(
8065 "GET / HTTP/1.1\r\n"
8066 "Host: www.example.org\r\n"
8067 "Connection: keep-alive\r\n"
8068 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428069 };
8070
8071 // Lastly, the server responds with the actual content.
8072 MockRead data_reads[] = {
8073 MockRead("HTTP/1.0 200 OK\r\n"),
8074 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8075 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068076 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428077 };
8078
[email protected]31a2bfe2010-02-09 08:03:398079 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8080 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078081 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428082
[email protected]49639fa2011-12-20 23:22:418083 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428084
[email protected]49639fa2011-12-20 23:22:418085 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428086 EXPECT_EQ(ERR_IO_PENDING, rv);
8087
8088 rv = callback.WaitForResult();
8089 EXPECT_EQ(OK, rv);
8090}
8091
[email protected]23e482282013-06-14 16:08:028092TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298093 HttpRequestInfo request;
8094 request.method = "GET";
bncce36dca22015-04-21 22:11:238095 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298096 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8097 "Chromium Ultra Awesome X Edition");
8098
rdsmith82957ad2015-09-16 19:42:038099 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098100 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8101 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418102 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278103
[email protected]da81f132010-08-18 23:39:298104 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178105 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8106 "Host: www.example.org:443\r\n"
8107 "Proxy-Connection: keep-alive\r\n"
8108 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298109 };
8110 MockRead data_reads[] = {
8111 // Return an error, so the transaction stops here (this test isn't
8112 // interested in the rest).
8113 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8114 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8115 MockRead("Proxy-Connection: close\r\n\r\n"),
8116 };
8117
8118 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8119 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078120 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298121
[email protected]49639fa2011-12-20 23:22:418122 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298123
[email protected]49639fa2011-12-20 23:22:418124 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:298125 EXPECT_EQ(ERR_IO_PENDING, rv);
8126
8127 rv = callback.WaitForResult();
8128 EXPECT_EQ(OK, rv);
8129}
8130
[email protected]23e482282013-06-14 16:08:028131TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428132 HttpRequestInfo request;
8133 request.method = "GET";
bncce36dca22015-04-21 22:11:238134 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428135 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:168136 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8137 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428138
danakj1fd259a02016-04-16 03:17:098139 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8140 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418141 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278142
[email protected]1c773ea12009-04-28 19:58:428143 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238144 MockWrite(
8145 "GET / HTTP/1.1\r\n"
8146 "Host: www.example.org\r\n"
8147 "Connection: keep-alive\r\n"
8148 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428149 };
8150
8151 // Lastly, the server responds with the actual content.
8152 MockRead data_reads[] = {
8153 MockRead("HTTP/1.0 200 OK\r\n"),
8154 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8155 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068156 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428157 };
8158
[email protected]31a2bfe2010-02-09 08:03:398159 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8160 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078161 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428162
[email protected]49639fa2011-12-20 23:22:418163 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428164
[email protected]49639fa2011-12-20 23:22:418165 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428166 EXPECT_EQ(ERR_IO_PENDING, rv);
8167
8168 rv = callback.WaitForResult();
8169 EXPECT_EQ(OK, rv);
8170}
8171
[email protected]23e482282013-06-14 16:08:028172TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428173 HttpRequestInfo request;
8174 request.method = "POST";
bncce36dca22015-04-21 22:11:238175 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428176
danakj1fd259a02016-04-16 03:17:098177 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8178 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418179 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278180
[email protected]1c773ea12009-04-28 19:58:428181 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238182 MockWrite(
8183 "POST / HTTP/1.1\r\n"
8184 "Host: www.example.org\r\n"
8185 "Connection: keep-alive\r\n"
8186 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428187 };
8188
8189 // Lastly, the server responds with the actual content.
8190 MockRead data_reads[] = {
8191 MockRead("HTTP/1.0 200 OK\r\n"),
8192 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8193 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068194 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428195 };
8196
[email protected]31a2bfe2010-02-09 08:03:398197 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8198 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078199 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428200
[email protected]49639fa2011-12-20 23:22:418201 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428202
[email protected]49639fa2011-12-20 23:22:418203 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428204 EXPECT_EQ(ERR_IO_PENDING, rv);
8205
8206 rv = callback.WaitForResult();
8207 EXPECT_EQ(OK, rv);
8208}
8209
[email protected]23e482282013-06-14 16:08:028210TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428211 HttpRequestInfo request;
8212 request.method = "PUT";
bncce36dca22015-04-21 22:11:238213 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428214
danakj1fd259a02016-04-16 03:17:098215 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8216 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418217 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278218
[email protected]1c773ea12009-04-28 19:58:428219 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238220 MockWrite(
8221 "PUT / HTTP/1.1\r\n"
8222 "Host: www.example.org\r\n"
8223 "Connection: keep-alive\r\n"
8224 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428225 };
8226
8227 // Lastly, the server responds with the actual content.
8228 MockRead data_reads[] = {
8229 MockRead("HTTP/1.0 200 OK\r\n"),
8230 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8231 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068232 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428233 };
8234
[email protected]31a2bfe2010-02-09 08:03:398235 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8236 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078237 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428238
[email protected]49639fa2011-12-20 23:22:418239 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428240
[email protected]49639fa2011-12-20 23:22:418241 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428242 EXPECT_EQ(ERR_IO_PENDING, rv);
8243
8244 rv = callback.WaitForResult();
8245 EXPECT_EQ(OK, rv);
8246}
8247
[email protected]23e482282013-06-14 16:08:028248TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428249 HttpRequestInfo request;
8250 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238251 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428252
danakj1fd259a02016-04-16 03:17:098253 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8254 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418255 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278256
[email protected]1c773ea12009-04-28 19:58:428257 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138258 MockWrite("HEAD / HTTP/1.1\r\n"
8259 "Host: www.example.org\r\n"
8260 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428261 };
8262
8263 // Lastly, the server responds with the actual content.
8264 MockRead data_reads[] = {
8265 MockRead("HTTP/1.0 200 OK\r\n"),
8266 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8267 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068268 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428269 };
8270
[email protected]31a2bfe2010-02-09 08:03:398271 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8272 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078273 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428274
[email protected]49639fa2011-12-20 23:22:418275 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428276
[email protected]49639fa2011-12-20 23:22:418277 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428278 EXPECT_EQ(ERR_IO_PENDING, rv);
8279
8280 rv = callback.WaitForResult();
8281 EXPECT_EQ(OK, rv);
8282}
8283
[email protected]23e482282013-06-14 16:08:028284TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428285 HttpRequestInfo request;
8286 request.method = "GET";
bncce36dca22015-04-21 22:11:238287 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428288 request.load_flags = LOAD_BYPASS_CACHE;
8289
danakj1fd259a02016-04-16 03:17:098290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8291 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418292 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278293
[email protected]1c773ea12009-04-28 19:58:428294 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238295 MockWrite(
8296 "GET / HTTP/1.1\r\n"
8297 "Host: www.example.org\r\n"
8298 "Connection: keep-alive\r\n"
8299 "Pragma: no-cache\r\n"
8300 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428301 };
8302
8303 // Lastly, the server responds with the actual content.
8304 MockRead data_reads[] = {
8305 MockRead("HTTP/1.0 200 OK\r\n"),
8306 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8307 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068308 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428309 };
8310
[email protected]31a2bfe2010-02-09 08:03:398311 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8312 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078313 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428314
[email protected]49639fa2011-12-20 23:22:418315 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428316
[email protected]49639fa2011-12-20 23:22:418317 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428318 EXPECT_EQ(ERR_IO_PENDING, rv);
8319
8320 rv = callback.WaitForResult();
8321 EXPECT_EQ(OK, rv);
8322}
8323
[email protected]23e482282013-06-14 16:08:028324TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:428325 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428326 HttpRequestInfo request;
8327 request.method = "GET";
bncce36dca22015-04-21 22:11:238328 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428329 request.load_flags = LOAD_VALIDATE_CACHE;
8330
danakj1fd259a02016-04-16 03:17:098331 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8332 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278334
[email protected]1c773ea12009-04-28 19:58:428335 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238336 MockWrite(
8337 "GET / HTTP/1.1\r\n"
8338 "Host: www.example.org\r\n"
8339 "Connection: keep-alive\r\n"
8340 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428341 };
8342
8343 // Lastly, the server responds with the actual content.
8344 MockRead data_reads[] = {
8345 MockRead("HTTP/1.0 200 OK\r\n"),
8346 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8347 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068348 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428349 };
8350
[email protected]31a2bfe2010-02-09 08:03:398351 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8352 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078353 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428354
[email protected]49639fa2011-12-20 23:22:418355 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428356
[email protected]49639fa2011-12-20 23:22:418357 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428358 EXPECT_EQ(ERR_IO_PENDING, rv);
8359
8360 rv = callback.WaitForResult();
8361 EXPECT_EQ(OK, rv);
8362}
8363
[email protected]23e482282013-06-14 16:08:028364TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428365 HttpRequestInfo request;
8366 request.method = "GET";
bncce36dca22015-04-21 22:11:238367 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438368 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428369
danakj1fd259a02016-04-16 03:17:098370 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8371 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418372 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278373
[email protected]1c773ea12009-04-28 19:58:428374 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238375 MockWrite(
8376 "GET / HTTP/1.1\r\n"
8377 "Host: www.example.org\r\n"
8378 "Connection: keep-alive\r\n"
8379 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428380 };
8381
8382 // Lastly, the server responds with the actual content.
8383 MockRead data_reads[] = {
8384 MockRead("HTTP/1.0 200 OK\r\n"),
8385 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8386 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068387 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428388 };
8389
[email protected]31a2bfe2010-02-09 08:03:398390 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8391 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078392 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428393
[email protected]49639fa2011-12-20 23:22:418394 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428395
[email protected]49639fa2011-12-20 23:22:418396 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428397 EXPECT_EQ(ERR_IO_PENDING, rv);
8398
8399 rv = callback.WaitForResult();
8400 EXPECT_EQ(OK, rv);
8401}
8402
[email protected]23e482282013-06-14 16:08:028403TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478404 HttpRequestInfo request;
8405 request.method = "GET";
bncce36dca22015-04-21 22:11:238406 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438407 request.extra_headers.SetHeader("referer", "www.foo.com");
8408 request.extra_headers.SetHeader("hEllo", "Kitty");
8409 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478410
danakj1fd259a02016-04-16 03:17:098411 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8412 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418413 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278414
[email protected]270c6412010-03-29 22:02:478415 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238416 MockWrite(
8417 "GET / HTTP/1.1\r\n"
8418 "Host: www.example.org\r\n"
8419 "Connection: keep-alive\r\n"
8420 "referer: www.foo.com\r\n"
8421 "hEllo: Kitty\r\n"
8422 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478423 };
8424
8425 // Lastly, the server responds with the actual content.
8426 MockRead data_reads[] = {
8427 MockRead("HTTP/1.0 200 OK\r\n"),
8428 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8429 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068430 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478431 };
8432
8433 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8434 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078435 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478436
[email protected]49639fa2011-12-20 23:22:418437 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478438
[email protected]49639fa2011-12-20 23:22:418439 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:478440 EXPECT_EQ(ERR_IO_PENDING, rv);
8441
8442 rv = callback.WaitForResult();
8443 EXPECT_EQ(OK, rv);
8444}
8445
[email protected]23e482282013-06-14 16:08:028446TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278447 HttpRequestInfo request;
8448 request.method = "GET";
bncce36dca22015-04-21 22:11:238449 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278450 request.load_flags = 0;
8451
rdsmith82957ad2015-09-16 19:42:038452 session_deps_.proxy_service =
8453 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518454 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078455 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028456
danakj1fd259a02016-04-16 03:17:098457 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8458 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418459 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028460
[email protected]3cd17242009-06-23 02:59:028461 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8462 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8463
8464 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238465 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8466 MockWrite(
8467 "GET / HTTP/1.1\r\n"
8468 "Host: www.example.org\r\n"
8469 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028470
8471 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068472 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028473 MockRead("HTTP/1.0 200 OK\r\n"),
8474 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8475 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068476 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028477 };
8478
[email protected]31a2bfe2010-02-09 08:03:398479 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8480 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078481 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028482
[email protected]49639fa2011-12-20 23:22:418483 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028484
[email protected]49639fa2011-12-20 23:22:418485 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028486 EXPECT_EQ(ERR_IO_PENDING, rv);
8487
8488 rv = callback.WaitForResult();
8489 EXPECT_EQ(OK, rv);
8490
8491 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528492 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028493
[email protected]029c83b62013-01-24 05:28:208494 LoadTimingInfo load_timing_info;
8495 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8496 TestLoadTimingNotReusedWithPac(load_timing_info,
8497 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8498
[email protected]3cd17242009-06-23 02:59:028499 std::string response_text;
8500 rv = ReadTransaction(trans.get(), &response_text);
8501 EXPECT_EQ(OK, rv);
8502 EXPECT_EQ("Payload", response_text);
8503}
8504
[email protected]23e482282013-06-14 16:08:028505TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278506 HttpRequestInfo request;
8507 request.method = "GET";
bncce36dca22015-04-21 22:11:238508 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278509 request.load_flags = 0;
8510
rdsmith82957ad2015-09-16 19:42:038511 session_deps_.proxy_service =
8512 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518513 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078514 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028515
danakj1fd259a02016-04-16 03:17:098516 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8517 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418518 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028519
[email protected]3cd17242009-06-23 02:59:028520 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8521 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8522
8523 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238524 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8525 arraysize(write_buffer)),
8526 MockWrite(
8527 "GET / HTTP/1.1\r\n"
8528 "Host: www.example.org\r\n"
8529 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028530
8531 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018532 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8533 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358534 MockRead("HTTP/1.0 200 OK\r\n"),
8535 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8536 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068537 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358538 };
8539
[email protected]31a2bfe2010-02-09 08:03:398540 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8541 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078542 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358543
[email protected]8ddf8322012-02-23 18:08:068544 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078545 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358546
[email protected]49639fa2011-12-20 23:22:418547 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358548
[email protected]49639fa2011-12-20 23:22:418549 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358550 EXPECT_EQ(ERR_IO_PENDING, rv);
8551
8552 rv = callback.WaitForResult();
8553 EXPECT_EQ(OK, rv);
8554
[email protected]029c83b62013-01-24 05:28:208555 LoadTimingInfo load_timing_info;
8556 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8557 TestLoadTimingNotReusedWithPac(load_timing_info,
8558 CONNECT_TIMING_HAS_SSL_TIMES);
8559
[email protected]e0c27be2009-07-15 13:09:358560 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528561 ASSERT_TRUE(response);
[email protected]e0c27be2009-07-15 13:09:358562
8563 std::string response_text;
8564 rv = ReadTransaction(trans.get(), &response_text);
8565 EXPECT_EQ(OK, rv);
8566 EXPECT_EQ("Payload", response_text);
8567}
8568
[email protected]23e482282013-06-14 16:08:028569TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:208570 HttpRequestInfo request;
8571 request.method = "GET";
bncce36dca22015-04-21 22:11:238572 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:208573 request.load_flags = 0;
8574
rdsmith82957ad2015-09-16 19:42:038575 session_deps_.proxy_service =
8576 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518577 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078578 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:208579
danakj1fd259a02016-04-16 03:17:098580 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8581 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418582 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:208583
8584 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8585 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8586
8587 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238588 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8589 MockWrite(
8590 "GET / HTTP/1.1\r\n"
8591 "Host: www.example.org\r\n"
8592 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:208593
8594 MockRead data_reads[] = {
8595 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
8596 MockRead("HTTP/1.0 200 OK\r\n"),
8597 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8598 MockRead("Payload"),
8599 MockRead(SYNCHRONOUS, OK)
8600 };
8601
8602 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8603 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078604 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:208605
8606 TestCompletionCallback callback;
8607
8608 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8609 EXPECT_EQ(ERR_IO_PENDING, rv);
8610
8611 rv = callback.WaitForResult();
8612 EXPECT_EQ(OK, rv);
8613
8614 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528615 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:208616
8617 LoadTimingInfo load_timing_info;
8618 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8619 TestLoadTimingNotReused(load_timing_info,
8620 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8621
8622 std::string response_text;
8623 rv = ReadTransaction(trans.get(), &response_text);
8624 EXPECT_EQ(OK, rv);
8625 EXPECT_EQ("Payload", response_text);
8626}
8627
[email protected]23e482282013-06-14 16:08:028628TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278629 HttpRequestInfo request;
8630 request.method = "GET";
bncce36dca22015-04-21 22:11:238631 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278632 request.load_flags = 0;
8633
rdsmith82957ad2015-09-16 19:42:038634 session_deps_.proxy_service =
8635 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518636 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078637 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358638
danakj1fd259a02016-04-16 03:17:098639 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8640 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418641 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358642
[email protected]e0c27be2009-07-15 13:09:358643 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8644 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378645 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238646 0x05, // Version
8647 0x01, // Command (CONNECT)
8648 0x00, // Reserved.
8649 0x03, // Address type (DOMAINNAME).
8650 0x0F, // Length of domain (15)
8651 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8652 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:378653 };
[email protected]e0c27be2009-07-15 13:09:358654 const char kSOCKS5OkResponse[] =
8655 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
8656
8657 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238658 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8659 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
8660 MockWrite(
8661 "GET / HTTP/1.1\r\n"
8662 "Host: www.example.org\r\n"
8663 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358664
8665 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018666 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8667 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:358668 MockRead("HTTP/1.0 200 OK\r\n"),
8669 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8670 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068671 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358672 };
8673
[email protected]31a2bfe2010-02-09 08:03:398674 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8675 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078676 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358677
[email protected]49639fa2011-12-20 23:22:418678 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358679
[email protected]49639fa2011-12-20 23:22:418680 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358681 EXPECT_EQ(ERR_IO_PENDING, rv);
8682
8683 rv = callback.WaitForResult();
8684 EXPECT_EQ(OK, rv);
8685
8686 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528687 ASSERT_TRUE(response);
[email protected]e0c27be2009-07-15 13:09:358688
[email protected]029c83b62013-01-24 05:28:208689 LoadTimingInfo load_timing_info;
8690 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8691 TestLoadTimingNotReusedWithPac(load_timing_info,
8692 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8693
[email protected]e0c27be2009-07-15 13:09:358694 std::string response_text;
8695 rv = ReadTransaction(trans.get(), &response_text);
8696 EXPECT_EQ(OK, rv);
8697 EXPECT_EQ("Payload", response_text);
8698}
8699
[email protected]23e482282013-06-14 16:08:028700TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278701 HttpRequestInfo request;
8702 request.method = "GET";
bncce36dca22015-04-21 22:11:238703 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278704 request.load_flags = 0;
8705
rdsmith82957ad2015-09-16 19:42:038706 session_deps_.proxy_service =
8707 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518708 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078709 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358710
danakj1fd259a02016-04-16 03:17:098711 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8712 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418713 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358714
[email protected]e0c27be2009-07-15 13:09:358715 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8716 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378717 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238718 0x05, // Version
8719 0x01, // Command (CONNECT)
8720 0x00, // Reserved.
8721 0x03, // Address type (DOMAINNAME).
8722 0x0F, // Length of domain (15)
8723 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8724 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:378725 };
8726
[email protected]e0c27be2009-07-15 13:09:358727 const char kSOCKS5OkResponse[] =
8728 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
8729
8730 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238731 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8732 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
8733 arraysize(kSOCKS5OkRequest)),
8734 MockWrite(
8735 "GET / HTTP/1.1\r\n"
8736 "Host: www.example.org\r\n"
8737 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358738
8739 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018740 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8741 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:028742 MockRead("HTTP/1.0 200 OK\r\n"),
8743 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8744 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068745 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028746 };
8747
[email protected]31a2bfe2010-02-09 08:03:398748 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8749 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078750 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028751
[email protected]8ddf8322012-02-23 18:08:068752 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:028754
[email protected]49639fa2011-12-20 23:22:418755 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028756
[email protected]49639fa2011-12-20 23:22:418757 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028758 EXPECT_EQ(ERR_IO_PENDING, rv);
8759
8760 rv = callback.WaitForResult();
8761 EXPECT_EQ(OK, rv);
8762
8763 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528764 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028765
[email protected]029c83b62013-01-24 05:28:208766 LoadTimingInfo load_timing_info;
8767 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8768 TestLoadTimingNotReusedWithPac(load_timing_info,
8769 CONNECT_TIMING_HAS_SSL_TIMES);
8770
[email protected]3cd17242009-06-23 02:59:028771 std::string response_text;
8772 rv = ReadTransaction(trans.get(), &response_text);
8773 EXPECT_EQ(OK, rv);
8774 EXPECT_EQ("Payload", response_text);
8775}
8776
[email protected]448d4ca52012-03-04 04:12:238777namespace {
8778
[email protected]04e5be32009-06-26 20:00:318779// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:068780
8781struct GroupNameTest {
8782 std::string proxy_server;
8783 std::string url;
8784 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:188785 bool ssl;
[email protected]2d731a32010-04-29 01:04:068786};
8787
danakj1fd259a02016-04-16 03:17:098788std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:438789 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:078790 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:098791 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:068792
[email protected]30d4c022013-07-18 22:58:168793 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538794 session->http_server_properties();
bnccacc0992015-03-20 20:22:228795 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:258796 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:128797 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:228798 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:468799 url::SchemeHostPort("http", "host.with.alternate", 80),
8800 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:068801
8802 return session;
8803}
8804
mmenkee65e7af2015-10-13 17:16:428805int GroupNameTransactionHelper(const std::string& url,
8806 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:068807 HttpRequestInfo request;
8808 request.method = "GET";
8809 request.url = GURL(url);
8810 request.load_flags = 0;
8811
danakj1fd259a02016-04-16 03:17:098812 std::unique_ptr<HttpTransaction> trans(
mmenkee65e7af2015-10-13 17:16:428813 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:278814
[email protected]49639fa2011-12-20 23:22:418815 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:068816
8817 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:418818 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:068819}
8820
[email protected]448d4ca52012-03-04 04:12:238821} // namespace
8822
[email protected]23e482282013-06-14 16:08:028823TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:068824 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238825 {
8826 "", // unused
8827 "http://www.example.org/direct",
8828 "www.example.org:80",
8829 false,
8830 },
8831 {
8832 "", // unused
8833 "http://[2001:1418:13:1::25]/direct",
8834 "[2001:1418:13:1::25]:80",
8835 false,
8836 },
[email protected]04e5be32009-06-26 20:00:318837
bncce36dca22015-04-21 22:11:238838 // SSL Tests
8839 {
8840 "", // unused
8841 "https://www.example.org/direct_ssl",
8842 "ssl/www.example.org:443",
8843 true,
8844 },
8845 {
8846 "", // unused
8847 "https://[2001:1418:13:1::25]/direct",
8848 "ssl/[2001:1418:13:1::25]:443",
8849 true,
8850 },
8851 {
8852 "", // unused
8853 "http://host.with.alternate/direct",
8854 "ssl/host.with.alternate:443",
8855 true,
8856 },
[email protected]2d731a32010-04-29 01:04:068857 };
[email protected]2ff8b312010-04-26 22:20:548858
bncf33fb31b2016-01-29 15:22:268859 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d731a32010-04-29 01:04:068860
viettrungluue4a8b882014-10-16 06:17:388861 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038862 session_deps_.proxy_service =
8863 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:098864 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:388865 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068866
mmenkee65e7af2015-10-13 17:16:428867 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:288868 CaptureGroupNameTransportSocketPool* transport_conn_pool =
8869 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138870 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348871 new CaptureGroupNameSSLSocketPool(NULL, NULL);
danakj1fd259a02016-04-16 03:17:098872 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:448873 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028874 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
8875 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:488876 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:068877
8878 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428879 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188880 if (tests[i].ssl)
8881 EXPECT_EQ(tests[i].expected_group_name,
8882 ssl_conn_pool->last_group_name_received());
8883 else
8884 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:288885 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068886 }
[email protected]2d731a32010-04-29 01:04:068887}
8888
[email protected]23e482282013-06-14 16:08:028889TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:068890 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238891 {
8892 "http_proxy",
8893 "http://www.example.org/http_proxy_normal",
8894 "www.example.org:80",
8895 false,
8896 },
[email protected]2d731a32010-04-29 01:04:068897
bncce36dca22015-04-21 22:11:238898 // SSL Tests
8899 {
8900 "http_proxy",
8901 "https://www.example.org/http_connect_ssl",
8902 "ssl/www.example.org:443",
8903 true,
8904 },
[email protected]af3490e2010-10-16 21:02:298905
bncce36dca22015-04-21 22:11:238906 {
8907 "http_proxy",
8908 "http://host.with.alternate/direct",
8909 "ssl/host.with.alternate:443",
8910 true,
8911 },
[email protected]45499252013-01-23 17:12:568912
bncce36dca22015-04-21 22:11:238913 {
8914 "http_proxy",
8915 "ftp://ftp.google.com/http_proxy_normal",
8916 "ftp/ftp.google.com:21",
8917 false,
8918 },
[email protected]2d731a32010-04-29 01:04:068919 };
8920
bncf33fb31b2016-01-29 15:22:268921 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d731a32010-04-29 01:04:068922
viettrungluue4a8b882014-10-16 06:17:388923 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038924 session_deps_.proxy_service =
8925 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:098926 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:388927 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068928
mmenkee65e7af2015-10-13 17:16:428929 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:068930
[email protected]e60e47a2010-07-14 03:37:188931 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138932 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348933 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138934 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348935 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028936
danakj1fd259a02016-04-16 03:17:098937 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:448938 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028939 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8940 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:488941 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:068942
8943 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428944 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188945 if (tests[i].ssl)
8946 EXPECT_EQ(tests[i].expected_group_name,
8947 ssl_conn_pool->last_group_name_received());
8948 else
8949 EXPECT_EQ(tests[i].expected_group_name,
8950 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068951 }
[email protected]2d731a32010-04-29 01:04:068952}
8953
[email protected]23e482282013-06-14 16:08:028954TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068955 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238956 {
8957 "socks4://socks_proxy:1080",
8958 "http://www.example.org/socks4_direct",
8959 "socks4/www.example.org:80",
8960 false,
8961 },
8962 {
8963 "socks5://socks_proxy:1080",
8964 "http://www.example.org/socks5_direct",
8965 "socks5/www.example.org:80",
8966 false,
8967 },
[email protected]2d731a32010-04-29 01:04:068968
bncce36dca22015-04-21 22:11:238969 // SSL Tests
8970 {
8971 "socks4://socks_proxy:1080",
8972 "https://www.example.org/socks4_ssl",
8973 "socks4/ssl/www.example.org:443",
8974 true,
8975 },
8976 {
8977 "socks5://socks_proxy:1080",
8978 "https://www.example.org/socks5_ssl",
8979 "socks5/ssl/www.example.org:443",
8980 true,
8981 },
[email protected]af3490e2010-10-16 21:02:298982
bncce36dca22015-04-21 22:11:238983 {
8984 "socks4://socks_proxy:1080",
8985 "http://host.with.alternate/direct",
8986 "socks4/ssl/host.with.alternate:443",
8987 true,
8988 },
[email protected]04e5be32009-06-26 20:00:318989 };
8990
bncf33fb31b2016-01-29 15:22:268991 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2ff8b312010-04-26 22:20:548992
viettrungluue4a8b882014-10-16 06:17:388993 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038994 session_deps_.proxy_service =
8995 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:098996 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:388997 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028998
mmenkee65e7af2015-10-13 17:16:428999 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319000
[email protected]e60e47a2010-07-14 03:37:189001 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139002 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349003 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139004 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349005 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029006
danakj1fd259a02016-04-16 03:17:099007 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449008 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029009 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
9010 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489011 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319012
danakj1fd259a02016-04-16 03:17:099013 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509014 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:319015
[email protected]2d731a32010-04-29 01:04:069016 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429017 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189018 if (tests[i].ssl)
9019 EXPECT_EQ(tests[i].expected_group_name,
9020 ssl_conn_pool->last_group_name_received());
9021 else
9022 EXPECT_EQ(tests[i].expected_group_name,
9023 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319024 }
9025}
9026
[email protected]23e482282013-06-14 16:08:029027TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279028 HttpRequestInfo request;
9029 request.method = "GET";
bncce36dca22015-04-21 22:11:239030 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279031
rdsmith82957ad2015-09-16 19:42:039032 session_deps_.proxy_service =
9033 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329034
[email protected]69719062010-01-05 20:09:219035 // This simulates failure resolving all hostnames; that means we will fail
9036 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079037 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329038
danakj1fd259a02016-04-16 03:17:099039 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9040 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419041 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:259042
[email protected]49639fa2011-12-20 23:22:419043 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259044
[email protected]49639fa2011-12-20 23:22:419045 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:259046 EXPECT_EQ(ERR_IO_PENDING, rv);
9047
[email protected]9172a982009-06-06 00:30:259048 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:019049 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:259050}
9051
[email protected]685af592010-05-11 19:31:249052// Base test to make sure that when the load flags for a request specify to
9053// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029054void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079055 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279056 // Issue a request, asking to bypass the cache(s).
9057 HttpRequestInfo request;
9058 request.method = "GET";
9059 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:239060 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279061
[email protected]a2c2fb92009-07-18 07:31:049062 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:079063 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:329064
danakj1fd259a02016-04-16 03:17:099065 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9066 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419067 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:289068
bncce36dca22015-04-21 22:11:239069 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289070 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299071 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:079072 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239073 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
9074 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:479075 EXPECT_EQ(ERR_IO_PENDING, rv);
9076 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289077 EXPECT_EQ(OK, rv);
9078
9079 // Verify that it was added to host cache, by doing a subsequent async lookup
9080 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:079081 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239082 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
9083 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:329084 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:289085
bncce36dca22015-04-21 22:11:239086 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289087 // we can tell if the next lookup hit the cache, or the "network".
9088 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239089 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289090
9091 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9092 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069093 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399094 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079095 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289096
[email protected]3b9cca42009-06-16 01:08:289097 // Run the request.
[email protected]49639fa2011-12-20 23:22:419098 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:289099 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419100 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289101
9102 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239103 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289104 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
9105}
9106
[email protected]685af592010-05-11 19:31:249107// There are multiple load flags that should trigger the host cache bypass.
9108// Test each in isolation:
[email protected]23e482282013-06-14 16:08:029109TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249110 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9111}
9112
[email protected]23e482282013-06-14 16:08:029113TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249114 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9115}
9116
[email protected]23e482282013-06-14 16:08:029117TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249118 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9119}
9120
[email protected]0877e3d2009-10-17 22:29:579121// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:029122TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579123 HttpRequestInfo request;
9124 request.method = "GET";
9125 request.url = GURL("http://www.foo.com/");
9126 request.load_flags = 0;
9127
9128 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069129 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579130 };
[email protected]31a2bfe2010-02-09 08:03:399131 StaticSocketDataProvider data(NULL, 0,
9132 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079133 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099134 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579135
[email protected]49639fa2011-12-20 23:22:419136 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579137
danakj1fd259a02016-04-16 03:17:099138 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419139 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579140
[email protected]49639fa2011-12-20 23:22:419141 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579142 EXPECT_EQ(ERR_IO_PENDING, rv);
9143
9144 rv = callback.WaitForResult();
9145 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:599146
9147 IPEndPoint endpoint;
9148 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
9149 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579150}
9151
zmo9528c9f42015-08-04 22:12:089152// Check that a connection closed after the start of the headers finishes ok.
9153TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579154 HttpRequestInfo request;
9155 request.method = "GET";
9156 request.url = GURL("http://www.foo.com/");
9157 request.load_flags = 0;
9158
9159 MockRead data_reads[] = {
9160 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069161 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579162 };
9163
[email protected]31a2bfe2010-02-09 08:03:399164 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079165 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099166 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579167
[email protected]49639fa2011-12-20 23:22:419168 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579169
danakj1fd259a02016-04-16 03:17:099170 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579172
[email protected]49639fa2011-12-20 23:22:419173 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579174 EXPECT_EQ(ERR_IO_PENDING, rv);
9175
9176 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:089177 EXPECT_EQ(OK, rv);
9178
9179 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529180 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089181
wezca1070932016-05-26 20:30:529182 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089183 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9184
9185 std::string response_data;
9186 rv = ReadTransaction(trans.get(), &response_data);
9187 EXPECT_EQ(OK, rv);
9188 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599189
9190 IPEndPoint endpoint;
9191 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
9192 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579193}
9194
9195// Make sure that a dropped connection while draining the body for auth
9196// restart does the right thing.
[email protected]23e482282013-06-14 16:08:029197TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579198 HttpRequestInfo request;
9199 request.method = "GET";
bncce36dca22015-04-21 22:11:239200 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579201 request.load_flags = 0;
9202
9203 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239204 MockWrite(
9205 "GET / HTTP/1.1\r\n"
9206 "Host: www.example.org\r\n"
9207 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579208 };
9209
9210 MockRead data_reads1[] = {
9211 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9212 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9213 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9214 MockRead("Content-Length: 14\r\n\r\n"),
9215 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069216 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579217 };
9218
[email protected]31a2bfe2010-02-09 08:03:399219 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9220 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079221 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579222
9223 // After calling trans->RestartWithAuth(), this is the request we should
9224 // be issuing -- the final header line contains the credentials.
9225 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239226 MockWrite(
9227 "GET / HTTP/1.1\r\n"
9228 "Host: www.example.org\r\n"
9229 "Connection: keep-alive\r\n"
9230 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579231 };
9232
9233 // Lastly, the server responds with the actual content.
9234 MockRead data_reads2[] = {
9235 MockRead("HTTP/1.1 200 OK\r\n"),
9236 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9237 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069238 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579239 };
9240
[email protected]31a2bfe2010-02-09 08:03:399241 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9242 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079243 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099244 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579245
[email protected]49639fa2011-12-20 23:22:419246 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579247
danakj1fd259a02016-04-16 03:17:099248 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509249 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509250
[email protected]49639fa2011-12-20 23:22:419251 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579252 EXPECT_EQ(ERR_IO_PENDING, rv);
9253
9254 rv = callback1.WaitForResult();
9255 EXPECT_EQ(OK, rv);
9256
9257 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529258 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049259 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579260
[email protected]49639fa2011-12-20 23:22:419261 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579262
[email protected]49639fa2011-12-20 23:22:419263 rv = trans->RestartWithAuth(
9264 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:579265 EXPECT_EQ(ERR_IO_PENDING, rv);
9266
9267 rv = callback2.WaitForResult();
9268 EXPECT_EQ(OK, rv);
9269
9270 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529271 ASSERT_TRUE(response);
9272 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579273 EXPECT_EQ(100, response->headers->GetContentLength());
9274}
9275
9276// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:029277TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039278 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579279
9280 HttpRequestInfo request;
9281 request.method = "GET";
bncce36dca22015-04-21 22:11:239282 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579283 request.load_flags = 0;
9284
9285 MockRead proxy_reads[] = {
9286 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069287 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579288 };
9289
[email protected]31a2bfe2010-02-09 08:03:399290 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069291 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579292
[email protected]bb88e1d32013-05-03 23:11:079293 session_deps_.socket_factory->AddSocketDataProvider(&data);
9294 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579295
[email protected]49639fa2011-12-20 23:22:419296 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579297
[email protected]bb88e1d32013-05-03 23:11:079298 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579299
danakj1fd259a02016-04-16 03:17:099300 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9301 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419302 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579303
[email protected]49639fa2011-12-20 23:22:419304 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579305 EXPECT_EQ(ERR_IO_PENDING, rv);
9306
9307 rv = callback.WaitForResult();
9308 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
9309}
9310
[email protected]23e482282013-06-14 16:08:029311TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469312 HttpRequestInfo request;
9313 request.method = "GET";
bncce36dca22015-04-21 22:11:239314 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469315 request.load_flags = 0;
9316
danakj1fd259a02016-04-16 03:17:099317 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9318 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419319 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:279320
[email protected]e22e1362009-11-23 21:31:129321 MockRead data_reads[] = {
9322 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069323 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129324 };
[email protected]9492e4a2010-02-24 00:58:469325
9326 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079327 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469328
[email protected]49639fa2011-12-20 23:22:419329 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469330
[email protected]49639fa2011-12-20 23:22:419331 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:469332 EXPECT_EQ(ERR_IO_PENDING, rv);
9333
9334 EXPECT_EQ(OK, callback.WaitForResult());
9335
9336 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529337 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469338
wezca1070932016-05-26 20:30:529339 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469340 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9341
9342 std::string response_data;
9343 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:239344 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:129345}
9346
[email protected]23e482282013-06-14 16:08:029347TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159348 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529349 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149350 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219351 UploadFileElementReader::ScopedOverridingContentLengthForTests
9352 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339353
danakj1fd259a02016-04-16 03:17:099354 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9355 element_readers.push_back(base::WrapUnique(new UploadFileElementReader(
avibf0746c2015-12-09 19:53:149356 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
9357 std::numeric_limits<uint64_t>::max(), base::Time())));
olli.raula6df48b2a2015-11-26 07:40:229358 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279359
9360 HttpRequestInfo request;
9361 request.method = "POST";
bncce36dca22015-04-21 22:11:239362 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279363 request.upload_data_stream = &upload_data_stream;
9364 request.load_flags = 0;
9365
danakj1fd259a02016-04-16 03:17:099366 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9367 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419368 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:339369
9370 MockRead data_reads[] = {
9371 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9372 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069373 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339374 };
[email protected]31a2bfe2010-02-09 08:03:399375 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079376 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339377
[email protected]49639fa2011-12-20 23:22:419378 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339379
[email protected]49639fa2011-12-20 23:22:419380 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:339381 EXPECT_EQ(ERR_IO_PENDING, rv);
9382
9383 rv = callback.WaitForResult();
9384 EXPECT_EQ(OK, rv);
9385
9386 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529387 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339388
wezca1070932016-05-26 20:30:529389 EXPECT_TRUE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339390 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9391
9392 std::string response_data;
9393 rv = ReadTransaction(trans.get(), &response_data);
9394 EXPECT_EQ(OK, rv);
9395 EXPECT_EQ("hello world", response_data);
9396
[email protected]dd3aa792013-07-16 19:10:239397 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339398}
9399
[email protected]23e482282013-06-14 16:08:029400TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159401 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529402 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369403 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309404 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369405 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119406 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369407
danakj1fd259a02016-04-16 03:17:099408 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9409 element_readers.push_back(base::WrapUnique(new UploadFileElementReader(
avibf0746c2015-12-09 19:53:149410 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
9411 std::numeric_limits<uint64_t>::max(), base::Time())));
olli.raula6df48b2a2015-11-26 07:40:229412 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279413
9414 HttpRequestInfo request;
9415 request.method = "POST";
bncce36dca22015-04-21 22:11:239416 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279417 request.upload_data_stream = &upload_data_stream;
9418 request.load_flags = 0;
9419
[email protected]999dd8c2013-11-12 06:45:549420 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9422 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419423 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:369424
[email protected]999dd8c2013-11-12 06:45:549425 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079426 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369427
[email protected]49639fa2011-12-20 23:22:419428 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369429
[email protected]49639fa2011-12-20 23:22:419430 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:369431 EXPECT_EQ(ERR_IO_PENDING, rv);
9432
9433 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:549434 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:369435
[email protected]dd3aa792013-07-16 19:10:239436 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369437}
9438
[email protected]02cad5d2013-10-02 08:14:039439TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
9440 class FakeUploadElementReader : public UploadElementReader {
9441 public:
9442 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209443 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039444
9445 const CompletionCallback& callback() const { return callback_; }
9446
9447 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209448 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039449 callback_ = callback;
9450 return ERR_IO_PENDING;
9451 }
avibf0746c2015-12-09 19:53:149452 uint64_t GetContentLength() const override { return 0; }
9453 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209454 int Read(IOBuffer* buf,
9455 int buf_length,
9456 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039457 return ERR_FAILED;
9458 }
9459
9460 private:
9461 CompletionCallback callback_;
9462 };
9463
9464 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099465 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9466 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229467 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039468
9469 HttpRequestInfo request;
9470 request.method = "POST";
bncce36dca22015-04-21 22:11:239471 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039472 request.upload_data_stream = &upload_data_stream;
9473 request.load_flags = 0;
9474
danakj1fd259a02016-04-16 03:17:099475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9476 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419477 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039478
9479 StaticSocketDataProvider data;
9480 session_deps_.socket_factory->AddSocketDataProvider(&data);
9481
9482 TestCompletionCallback callback;
9483 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9484 EXPECT_EQ(ERR_IO_PENDING, rv);
9485 base::MessageLoop::current()->RunUntilIdle();
9486
9487 // Transaction is pending on request body initialization.
9488 ASSERT_FALSE(fake_reader->callback().is_null());
9489
9490 // Return Init()'s result after the transaction gets destroyed.
9491 trans.reset();
9492 fake_reader->callback().Run(OK); // Should not crash.
9493}
9494
[email protected]aeefc9e82010-02-19 16:18:279495// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:029496TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279497 HttpRequestInfo request;
9498 request.method = "GET";
bncce36dca22015-04-21 22:11:239499 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279500 request.load_flags = 0;
9501
9502 // First transaction will request a resource and receive a Basic challenge
9503 // with realm="first_realm".
9504 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239505 MockWrite(
9506 "GET / HTTP/1.1\r\n"
9507 "Host: www.example.org\r\n"
9508 "Connection: keep-alive\r\n"
9509 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279510 };
9511 MockRead data_reads1[] = {
9512 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9513 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9514 "\r\n"),
9515 };
9516
9517 // After calling trans->RestartWithAuth(), provide an Authentication header
9518 // for first_realm. The server will reject and provide a challenge with
9519 // second_realm.
9520 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239521 MockWrite(
9522 "GET / HTTP/1.1\r\n"
9523 "Host: www.example.org\r\n"
9524 "Connection: keep-alive\r\n"
9525 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9526 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279527 };
9528 MockRead data_reads2[] = {
9529 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9530 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9531 "\r\n"),
9532 };
9533
9534 // This again fails, and goes back to first_realm. Make sure that the
9535 // entry is removed from cache.
9536 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239537 MockWrite(
9538 "GET / HTTP/1.1\r\n"
9539 "Host: www.example.org\r\n"
9540 "Connection: keep-alive\r\n"
9541 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9542 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279543 };
9544 MockRead data_reads3[] = {
9545 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9546 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9547 "\r\n"),
9548 };
9549
9550 // Try one last time (with the correct password) and get the resource.
9551 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239552 MockWrite(
9553 "GET / HTTP/1.1\r\n"
9554 "Host: www.example.org\r\n"
9555 "Connection: keep-alive\r\n"
9556 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9557 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279558 };
9559 MockRead data_reads4[] = {
9560 MockRead("HTTP/1.1 200 OK\r\n"
9561 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509562 "Content-Length: 5\r\n"
9563 "\r\n"
9564 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279565 };
9566
9567 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9568 data_writes1, arraysize(data_writes1));
9569 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9570 data_writes2, arraysize(data_writes2));
9571 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9572 data_writes3, arraysize(data_writes3));
9573 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9574 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079575 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9576 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9577 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9578 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279579
[email protected]49639fa2011-12-20 23:22:419580 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279581
danakj1fd259a02016-04-16 03:17:099582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9583 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419584 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509585
[email protected]aeefc9e82010-02-19 16:18:279586 // Issue the first request with Authorize headers. There should be a
9587 // password prompt for first_realm waiting to be filled in after the
9588 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419589 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:279590 EXPECT_EQ(ERR_IO_PENDING, rv);
9591 rv = callback1.WaitForResult();
9592 EXPECT_EQ(OK, rv);
9593 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529594 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049595 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529596 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049597 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239598 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049599 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199600 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279601
9602 // Issue the second request with an incorrect password. There should be a
9603 // password prompt for second_realm waiting to be filled in after the
9604 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419605 TestCompletionCallback callback2;
9606 rv = trans->RestartWithAuth(
9607 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:279608 EXPECT_EQ(ERR_IO_PENDING, rv);
9609 rv = callback2.WaitForResult();
9610 EXPECT_EQ(OK, rv);
9611 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529612 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049613 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529614 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049615 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239616 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049617 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199618 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279619
9620 // Issue the third request with another incorrect password. There should be
9621 // a password prompt for first_realm waiting to be filled in. If the password
9622 // prompt is not present, it indicates that the HttpAuthCacheEntry for
9623 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:419624 TestCompletionCallback callback3;
9625 rv = trans->RestartWithAuth(
9626 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:279627 EXPECT_EQ(ERR_IO_PENDING, rv);
9628 rv = callback3.WaitForResult();
9629 EXPECT_EQ(OK, rv);
9630 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529631 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049632 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529633 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049634 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239635 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049636 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199637 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279638
9639 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:419640 TestCompletionCallback callback4;
9641 rv = trans->RestartWithAuth(
9642 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:279643 EXPECT_EQ(ERR_IO_PENDING, rv);
9644 rv = callback4.WaitForResult();
9645 EXPECT_EQ(OK, rv);
9646 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529647 ASSERT_TRUE(response);
9648 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:279649}
9650
bncc958faa2015-07-31 18:14:529651TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:269652 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:529653
9654 std::string alternative_service_http_header =
9655 GetAlternativeServiceHttpHeader();
9656
9657 MockRead data_reads[] = {
9658 MockRead("HTTP/1.1 200 OK\r\n"),
9659 MockRead(alternative_service_http_header.c_str()),
9660 MockRead("\r\n"),
9661 MockRead("hello world"),
9662 MockRead(SYNCHRONOUS, OK),
9663 };
9664
9665 HttpRequestInfo request;
9666 request.method = "GET";
9667 request.url = GURL("http://www.example.org/");
9668 request.load_flags = 0;
9669
9670 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9671
9672 session_deps_.socket_factory->AddSocketDataProvider(&data);
9673
9674 TestCompletionCallback callback;
9675
danakj1fd259a02016-04-16 03:17:099676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9677 std::unique_ptr<HttpTransaction> trans(
bncc958faa2015-07-31 18:14:529678 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9679
9680 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9681 EXPECT_EQ(ERR_IO_PENDING, rv);
9682
zhongyi3d4a55e72016-04-22 20:36:469683 url::SchemeHostPort test_server("http", "www.example.org", 80);
bncc958faa2015-07-31 18:14:529684 HttpServerProperties& http_server_properties =
9685 *session->http_server_properties();
9686 AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469687 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529688 EXPECT_TRUE(alternative_service_vector.empty());
9689
9690 EXPECT_EQ(OK, callback.WaitForResult());
9691
9692 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529693 ASSERT_TRUE(response);
9694 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:529695 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9696 EXPECT_FALSE(response->was_fetched_via_spdy);
9697 EXPECT_FALSE(response->was_npn_negotiated);
9698
9699 std::string response_data;
9700 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9701 EXPECT_EQ("hello world", response_data);
9702
9703 alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469704 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529705 ASSERT_EQ(1u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:389706 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:529707 alternative_service_vector[0].protocol);
bnc8bef8da22016-05-30 01:28:259708 EXPECT_EQ("www.example.org", alternative_service_vector[0].host);
bncc958faa2015-07-31 18:14:529709 EXPECT_EQ(443, alternative_service_vector[0].port);
9710}
9711
bnc8bef8da22016-05-30 01:28:259712// HTTP/2 Alternative Services should be disabled if alternative service
9713// hostname is different from that of origin.
9714// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
9715TEST_P(HttpNetworkTransactionTest,
9716 DisableHTTP2AlternativeServicesWithDifferentHost) {
9717 session_deps_.enable_alternative_service_with_different_host = true;
9718
9719 HttpRequestInfo request;
9720 request.method = "GET";
9721 request.url = GURL("http://www.example.org/");
9722 request.load_flags = 0;
9723
9724 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9725 StaticSocketDataProvider first_data;
9726 first_data.set_connect_data(mock_connect);
9727 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
9728
9729 MockRead data_reads[] = {
9730 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9731 MockRead(ASYNC, OK),
9732 };
9733 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
9734 0);
9735 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9736
9737 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9738
9739 base::WeakPtr<HttpServerProperties> http_server_properties =
9740 session->http_server_properties();
9741 AlternativeService alternative_service(
9742 AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
9743 444);
9744 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9745 http_server_properties->SetAlternativeService(
9746 url::SchemeHostPort(request.url), alternative_service, expiration);
9747
9748 std::unique_ptr<HttpTransaction> trans(
9749 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9750 TestCompletionCallback callback;
9751
9752 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9753 // Alternative service is not used, request fails.
9754 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
9755}
9756
bnc4f575852015-10-14 18:35:089757TEST_P(HttpNetworkTransactionTest, ClearAlternativeServices) {
bncf33fb31b2016-01-29 15:22:269758 session_deps_.enable_alternative_service_with_different_host = false;
bnc4f575852015-10-14 18:35:089759
9760 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:099761 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc4f575852015-10-14 18:35:089762 HttpServerProperties& http_server_properties =
9763 *session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:469764 url::SchemeHostPort test_server("http", "www.example.org", 80);
bnc4f575852015-10-14 18:35:089765 AlternativeService alternative_service(QUIC, "", 80);
9766 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:469767 http_server_properties.SetAlternativeService(test_server, alternative_service,
9768 expiration);
bnc4f575852015-10-14 18:35:089769 AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469770 http_server_properties.GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:089771 EXPECT_EQ(1u, alternative_service_vector.size());
9772
9773 // Send a clear header.
9774 MockRead data_reads[] = {
9775 MockRead("HTTP/1.1 200 OK\r\n"),
9776 MockRead("Alt-Svc: clear\r\n"),
9777 MockRead("\r\n"),
9778 MockRead("hello world"),
9779 MockRead(SYNCHRONOUS, OK),
9780 };
9781 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
9782 session_deps_.socket_factory->AddSocketDataProvider(&data);
9783
9784 HttpRequestInfo request;
9785 request.method = "GET";
9786 request.url = GURL("http://www.example.org/");
9787 request.load_flags = 0;
9788
9789 TestCompletionCallback callback;
9790
danakj1fd259a02016-04-16 03:17:099791 std::unique_ptr<HttpTransaction> trans(
bnc4f575852015-10-14 18:35:089792 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9793
9794 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9795 EXPECT_EQ(OK, callback.GetResult(rv));
9796
9797 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529798 ASSERT_TRUE(response);
9799 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:089800 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9801 EXPECT_FALSE(response->was_fetched_via_spdy);
9802 EXPECT_FALSE(response->was_npn_negotiated);
9803
9804 std::string response_data;
9805 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9806 EXPECT_EQ("hello world", response_data);
9807
9808 alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469809 http_server_properties.GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:089810 EXPECT_TRUE(alternative_service_vector.empty());
9811}
9812
bncc958faa2015-07-31 18:14:529813TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:269814 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:529815
9816 MockRead data_reads[] = {
9817 MockRead("HTTP/1.1 200 OK\r\n"),
9818 MockRead("Alt-Svc: "),
9819 MockRead(GetAlternateProtocolFromParam()),
bnc44858c82015-10-16 11:57:219820 MockRead("=\"www.example.com:443\";p=\"1.0\","),
bnc3f0118e2016-02-02 15:42:229821 MockRead(GetAlternateProtocolFromParam()),
9822 MockRead("=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:529823 MockRead("hello world"),
9824 MockRead(SYNCHRONOUS, OK),
9825 };
9826
9827 HttpRequestInfo request;
9828 request.method = "GET";
9829 request.url = GURL("http://www.example.org/");
9830 request.load_flags = 0;
9831
9832 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9833
9834 session_deps_.socket_factory->AddSocketDataProvider(&data);
9835
9836 TestCompletionCallback callback;
9837
danakj1fd259a02016-04-16 03:17:099838 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9839 std::unique_ptr<HttpTransaction> trans(
bncc958faa2015-07-31 18:14:529840 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9841
9842 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9843 EXPECT_EQ(ERR_IO_PENDING, rv);
9844
zhongyi3d4a55e72016-04-22 20:36:469845 url::SchemeHostPort test_server("http", "www.example.org", 80);
bncc958faa2015-07-31 18:14:529846 HttpServerProperties& http_server_properties =
9847 *session->http_server_properties();
9848 AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469849 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529850 EXPECT_TRUE(alternative_service_vector.empty());
9851
9852 EXPECT_EQ(OK, callback.WaitForResult());
9853
9854 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529855 ASSERT_TRUE(response);
9856 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:529857 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9858 EXPECT_FALSE(response->was_fetched_via_spdy);
9859 EXPECT_FALSE(response->was_npn_negotiated);
9860
9861 std::string response_data;
9862 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9863 EXPECT_EQ("hello world", response_data);
9864
9865 alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469866 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529867 ASSERT_EQ(2u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:389868 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:529869 alternative_service_vector[0].protocol);
9870 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9871 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc3f0118e2016-02-02 15:42:229872 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
9873 alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:529874 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
9875 EXPECT_EQ(1234, alternative_service_vector[1].port);
9876}
9877
bncf33fb31b2016-01-29 15:22:269878// When |enable_alternative_service_with_different_host| is false, do not
9879// observe alternative service entries that point to a different host.
bnc54ec34b72015-08-26 19:34:569880TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
bncf33fb31b2016-01-29 15:22:269881 session_deps_.enable_alternative_service_with_different_host = false;
bnc54ec34b72015-08-26 19:34:569882
9883 HttpRequestInfo request;
9884 request.method = "GET";
9885 request.url = GURL("http://www.example.org/");
9886 request.load_flags = 0;
9887
9888 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9889 StaticSocketDataProvider first_data;
9890 first_data.set_connect_data(mock_connect);
9891 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
9892
9893 MockRead data_reads[] = {
9894 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9895 MockRead(ASYNC, OK),
9896 };
9897 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
9898 nullptr, 0);
9899 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9900
danakj1fd259a02016-04-16 03:17:099901 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:569902
9903 base::WeakPtr<HttpServerProperties> http_server_properties =
9904 session->http_server_properties();
9905 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:389906 AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
9907 80);
bnc54ec34b72015-08-26 19:34:569908 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9909 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:469910 url::SchemeHostPort(request.url), alternative_service, expiration);
bnc54ec34b72015-08-26 19:34:569911
danakj1fd259a02016-04-16 03:17:099912 std::unique_ptr<HttpTransaction> trans(
bnc54ec34b72015-08-26 19:34:569913 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9914 TestCompletionCallback callback;
9915
9916 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9917 // The connetion to origin was refused, and the alternative service should not
9918 // be used (even though mock data are there), therefore the request should
9919 // fail.
9920 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
9921}
9922
zhongyi48704c182015-12-07 07:52:029923TEST_P(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:469924 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:029925 HostPortPair alternative("alternative.example.org", 443);
9926 std::string origin_url = "https://origin.example.org:443";
9927 std::string alternative_url = "https://alternative.example.org:443";
9928
9929 // Negotiate HTTP/1.1 with alternative.example.org.
9930 SSLSocketDataProvider ssl(ASYNC, OK);
9931 ssl.SetNextProto(kProtoHTTP11);
9932 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9933
9934 // HTTP/1.1 data for request.
9935 MockWrite http_writes[] = {
9936 MockWrite("GET / HTTP/1.1\r\n"
9937 "Host: alternative.example.org\r\n"
9938 "Connection: keep-alive\r\n\r\n"),
9939 };
9940
9941 MockRead http_reads[] = {
9942 MockRead("HTTP/1.1 200 OK\r\n"
9943 "Content-Type: text/html; charset=iso-8859-1\r\n"
9944 "Content-Length: 40\r\n\r\n"
9945 "first HTTP/1.1 response from alternative"),
9946 };
9947 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
9948 http_writes, arraysize(http_writes));
9949 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
9950
9951 StaticSocketDataProvider data_refused;
9952 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
9953 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
9954
zhongyi3d4a55e72016-04-22 20:36:469955 // Set up a QUIC alternative service for server.
bncf33fb31b2016-01-29 15:22:269956 session_deps_.enable_alternative_service_with_different_host = false;
danakj1fd259a02016-04-16 03:17:099957 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zhongyi48704c182015-12-07 07:52:029958 base::WeakPtr<HttpServerProperties> http_server_properties =
9959 session->http_server_properties();
9960 AlternativeService alternative_service(QUIC, alternative);
9961 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:469962 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:509963 expiration);
zhongyi48704c182015-12-07 07:52:029964 // Mark the QUIC alternative service as broken.
9965 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
9966
danakj1fd259a02016-04-16 03:17:099967 std::unique_ptr<HttpTransaction> trans(
zhongyi48704c182015-12-07 07:52:029968 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9969 HttpRequestInfo request;
9970 request.method = "GET";
9971 request.url = GURL(origin_url);
9972 request.load_flags = 0;
9973 TestCompletionCallback callback;
9974 NetErrorDetails details;
9975 EXPECT_FALSE(details.quic_broken);
9976
9977 trans->Start(&request, callback.callback(), BoundNetLog());
9978 trans->PopulateNetErrorDetails(&details);
9979 EXPECT_TRUE(details.quic_broken);
9980}
9981
9982TEST_P(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:469983 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:029984 HostPortPair alternative1("alternative1.example.org", 443);
9985 HostPortPair alternative2("alternative2.example.org", 443);
9986 std::string origin_url = "https://origin.example.org:443";
9987 std::string alternative_url1 = "https://alternative1.example.org:443";
9988 std::string alternative_url2 = "https://alternative2.example.org:443";
9989
9990 // Negotiate HTTP/1.1 with alternative1.example.org.
9991 SSLSocketDataProvider ssl(ASYNC, OK);
9992 ssl.SetNextProto(kProtoHTTP11);
9993 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9994
9995 // HTTP/1.1 data for request.
9996 MockWrite http_writes[] = {
9997 MockWrite("GET / HTTP/1.1\r\n"
9998 "Host: alternative1.example.org\r\n"
9999 "Connection: keep-alive\r\n\r\n"),
10000 };
10001
10002 MockRead http_reads[] = {
10003 MockRead("HTTP/1.1 200 OK\r\n"
10004 "Content-Type: text/html; charset=iso-8859-1\r\n"
10005 "Content-Length: 40\r\n\r\n"
10006 "first HTTP/1.1 response from alternative1"),
10007 };
10008 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10009 http_writes, arraysize(http_writes));
10010 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10011
10012 StaticSocketDataProvider data_refused;
10013 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10014 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10015
bncf33fb31b2016-01-29 15:22:2610016 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0910017 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zhongyi48704c182015-12-07 07:52:0210018 base::WeakPtr<HttpServerProperties> http_server_properties =
10019 session->http_server_properties();
10020
zhongyi3d4a55e72016-04-22 20:36:4610021 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210022 AlternativeServiceInfoVector alternative_service_info_vector;
10023 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10024
10025 AlternativeService alternative_service1(QUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010026 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210027 expiration);
10028 alternative_service_info_vector.push_back(alternative_service_info1);
10029 AlternativeService alternative_service2(QUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010030 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210031 expiration);
10032 alternative_service_info_vector.push_back(alternative_service_info2);
10033
10034 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610035 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210036
10037 // Mark one of the QUIC alternative service as broken.
10038 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10039
10040 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610041 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:0210042
danakj1fd259a02016-04-16 03:17:0910043 std::unique_ptr<HttpTransaction> trans(
zhongyi48704c182015-12-07 07:52:0210044 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10045 HttpRequestInfo request;
10046 request.method = "GET";
10047 request.url = GURL(origin_url);
10048 request.load_flags = 0;
10049 TestCompletionCallback callback;
10050 NetErrorDetails details;
10051 EXPECT_FALSE(details.quic_broken);
10052
10053 trans->Start(&request, callback.callback(), BoundNetLog());
10054 trans->PopulateNetErrorDetails(&details);
10055 EXPECT_FALSE(details.quic_broken);
10056}
10057
[email protected]23e482282013-06-14 16:08:0210058TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310059 MarkBrokenAlternateProtocolAndFallback) {
bncf33fb31b2016-01-29 15:22:2610060 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]564b4912010-03-09 16:30:4210061
10062 HttpRequestInfo request;
10063 request.method = "GET";
bncce36dca22015-04-21 22:11:2310064 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210065 request.load_flags = 0;
10066
[email protected]d973e99a2012-02-17 21:02:3610067 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210068 StaticSocketDataProvider first_data;
10069 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710070 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:4210071
10072 MockRead data_reads[] = {
10073 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10074 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610075 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210076 };
10077 StaticSocketDataProvider second_data(
10078 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710079 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210080
danakj1fd259a02016-04-16 03:17:0910081 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210082
[email protected]30d4c022013-07-18 22:58:1610083 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310084 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610085 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110086 // Port must be < 1024, or the header will be ignored (since initial port was
10087 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010088 const AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810089 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bncd9b132e2015-07-08 05:16:1010090 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210091 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610092 http_server_properties->SetAlternativeService(server, alternative_service,
10093 expiration);
[email protected]564b4912010-03-09 16:30:4210094
danakj1fd259a02016-04-16 03:17:0910095 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010096 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110097 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210098
[email protected]49639fa2011-12-20 23:22:4110099 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:4210100 EXPECT_EQ(ERR_IO_PENDING, rv);
10101 EXPECT_EQ(OK, callback.WaitForResult());
10102
10103 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210104 ASSERT_TRUE(response);
10105 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210106 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10107
10108 std::string response_data;
10109 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10110 EXPECT_EQ("hello world", response_data);
10111
bncd9b132e2015-07-08 05:16:1010112 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610113 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010114 ASSERT_EQ(1u, alternative_service_vector.size());
10115 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10116 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10117 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210118}
10119
bnc55ff9da2015-08-19 18:42:3510120// Ensure that we are not allowed to redirect traffic via an alternate protocol
10121// to an unrestricted (port >= 1024) when the original traffic was on a
10122// restricted port (port < 1024). Ensure that we can redirect in all other
10123// cases.
[email protected]23e482282013-06-14 16:08:0210124TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310125 AlternateProtocolPortRestrictedBlocked) {
bncf33fb31b2016-01-29 15:22:2610126 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110127
10128 HttpRequestInfo restricted_port_request;
10129 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310130 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110131 restricted_port_request.load_flags = 0;
10132
[email protected]d973e99a2012-02-17 21:02:3610133 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110134 StaticSocketDataProvider first_data;
10135 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710136 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110137
10138 MockRead data_reads[] = {
10139 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10140 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610141 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110142 };
10143 StaticSocketDataProvider second_data(
10144 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710145 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110146
danakj1fd259a02016-04-16 03:17:0910147 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110148
[email protected]30d4c022013-07-18 22:58:1610149 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310150 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110151 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210152 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810153 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210154 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210155 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210156 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610157 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010158 expiration);
[email protected]3912662a32011-10-04 00:51:1110159
danakj1fd259a02016-04-16 03:17:0910160 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010161 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110162 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110163
[email protected]49639fa2011-12-20 23:22:4110164 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610165 &restricted_port_request,
10166 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110167 EXPECT_EQ(ERR_IO_PENDING, rv);
10168 // Invalid change to unrestricted port should fail.
10169 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:1910170}
[email protected]3912662a32011-10-04 00:51:1110171
bnc55ff9da2015-08-19 18:42:3510172// Ensure that we are allowed to redirect traffic via an alternate protocol to
10173// an unrestricted (port >= 1024) when the original traffic was on a restricted
10174// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:0210175TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:1910176 AlternateProtocolPortRestrictedPermitted) {
bncf33fb31b2016-01-29 15:22:2610177 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]bb88e1d32013-05-03 23:11:0710178 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910179
10180 HttpRequestInfo restricted_port_request;
10181 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310182 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910183 restricted_port_request.load_flags = 0;
10184
10185 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10186 StaticSocketDataProvider first_data;
10187 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710188 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910189
10190 MockRead data_reads[] = {
10191 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10192 MockRead("hello world"),
10193 MockRead(ASYNC, OK),
10194 };
10195 StaticSocketDataProvider second_data(
10196 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710197 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:1910198
danakj1fd259a02016-04-16 03:17:0910199 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910200
[email protected]30d4c022013-07-18 22:58:1610201 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910202 session->http_server_properties();
10203 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210204 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810205 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210206 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210207 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210208 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610209 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010210 expiration);
[email protected]c54c6962013-02-01 04:53:1910211
danakj1fd259a02016-04-16 03:17:0910212 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010213 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:1910214 TestCompletionCallback callback;
10215
10216 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:3610217 &restricted_port_request,
10218 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:1910219 // Change to unrestricted port should succeed.
10220 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110221}
10222
bnc55ff9da2015-08-19 18:42:3510223// Ensure that we are not allowed to redirect traffic via an alternate protocol
10224// to an unrestricted (port >= 1024) when the original traffic was on a
10225// restricted port (port < 1024). Ensure that we can redirect in all other
10226// cases.
[email protected]23e482282013-06-14 16:08:0210227TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310228 AlternateProtocolPortRestrictedAllowed) {
bncf33fb31b2016-01-29 15:22:2610229 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110230
10231 HttpRequestInfo restricted_port_request;
10232 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310233 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110234 restricted_port_request.load_flags = 0;
10235
[email protected]d973e99a2012-02-17 21:02:3610236 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110237 StaticSocketDataProvider first_data;
10238 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710239 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110240
10241 MockRead data_reads[] = {
10242 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10243 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610244 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110245 };
10246 StaticSocketDataProvider second_data(
10247 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710248 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110249
danakj1fd259a02016-04-16 03:17:0910250 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110251
[email protected]30d4c022013-07-18 22:58:1610252 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310253 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110254 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210255 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810256 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210257 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210258 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210259 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610260 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010261 expiration);
[email protected]3912662a32011-10-04 00:51:1110262
danakj1fd259a02016-04-16 03:17:0910263 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010264 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110265 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110266
[email protected]49639fa2011-12-20 23:22:4110267 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610268 &restricted_port_request,
10269 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110270 EXPECT_EQ(ERR_IO_PENDING, rv);
10271 // Valid change to restricted port should pass.
10272 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110273}
10274
bnc55ff9da2015-08-19 18:42:3510275// Ensure that we are not allowed to redirect traffic via an alternate protocol
10276// to an unrestricted (port >= 1024) when the original traffic was on a
10277// restricted port (port < 1024). Ensure that we can redirect in all other
10278// cases.
[email protected]23e482282013-06-14 16:08:0210279TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310280 AlternateProtocolPortUnrestrictedAllowed1) {
bncf33fb31b2016-01-29 15:22:2610281 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110282
10283 HttpRequestInfo unrestricted_port_request;
10284 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310285 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110286 unrestricted_port_request.load_flags = 0;
10287
[email protected]d973e99a2012-02-17 21:02:3610288 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110289 StaticSocketDataProvider first_data;
10290 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710291 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110292
10293 MockRead data_reads[] = {
10294 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10295 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610296 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110297 };
10298 StaticSocketDataProvider second_data(
10299 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710300 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110301
danakj1fd259a02016-04-16 03:17:0910302 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110303
[email protected]30d4c022013-07-18 22:58:1610304 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310305 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110306 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210307 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810308 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210309 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210310 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210311 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610312 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010313 expiration);
[email protected]3912662a32011-10-04 00:51:1110314
danakj1fd259a02016-04-16 03:17:0910315 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010316 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110317 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110318
[email protected]49639fa2011-12-20 23:22:4110319 int rv = trans->Start(
10320 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110321 EXPECT_EQ(ERR_IO_PENDING, rv);
10322 // Valid change to restricted port should pass.
10323 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110324}
10325
bnc55ff9da2015-08-19 18:42:3510326// Ensure that we are not allowed to redirect traffic via an alternate protocol
10327// to an unrestricted (port >= 1024) when the original traffic was on a
10328// restricted port (port < 1024). Ensure that we can redirect in all other
10329// cases.
[email protected]23e482282013-06-14 16:08:0210330TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310331 AlternateProtocolPortUnrestrictedAllowed2) {
bncf33fb31b2016-01-29 15:22:2610332 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110333
10334 HttpRequestInfo unrestricted_port_request;
10335 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310336 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110337 unrestricted_port_request.load_flags = 0;
10338
[email protected]d973e99a2012-02-17 21:02:3610339 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110340 StaticSocketDataProvider first_data;
10341 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710342 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110343
10344 MockRead data_reads[] = {
10345 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10346 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610347 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110348 };
10349 StaticSocketDataProvider second_data(
10350 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710351 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110352
danakj1fd259a02016-04-16 03:17:0910353 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110354
[email protected]30d4c022013-07-18 22:58:1610355 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310356 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210357 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:2210358 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810359 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210360 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210361 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210362 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610363 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010364 expiration);
[email protected]3912662a32011-10-04 00:51:1110365
danakj1fd259a02016-04-16 03:17:0910366 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010367 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110368 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110369
[email protected]49639fa2011-12-20 23:22:4110370 int rv = trans->Start(
10371 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110372 EXPECT_EQ(ERR_IO_PENDING, rv);
10373 // Valid change to an unrestricted port should pass.
10374 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110375}
10376
bnc55ff9da2015-08-19 18:42:3510377// Ensure that we are not allowed to redirect traffic via an alternate protocol
10378// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10379// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:2310380TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bncf33fb31b2016-01-29 15:22:2610381 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]eb6234e2012-01-19 01:50:0210382
10383 HttpRequestInfo request;
10384 request.method = "GET";
bncce36dca22015-04-21 22:11:2310385 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210386 request.load_flags = 0;
10387
10388 // The alternate protocol request will error out before we attempt to connect,
10389 // so only the standard HTTP request will try to connect.
10390 MockRead data_reads[] = {
10391 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10392 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610393 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210394 };
10395 StaticSocketDataProvider data(
10396 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710397 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210398
danakj1fd259a02016-04-16 03:17:0910399 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210400
[email protected]30d4c022013-07-18 22:58:1610401 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210402 session->http_server_properties();
10403 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:2210404 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810405 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210406 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210407 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210408 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610409 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210410
danakj1fd259a02016-04-16 03:17:0910411 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010412 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:0210413 TestCompletionCallback callback;
10414
10415 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10416 EXPECT_EQ(ERR_IO_PENDING, rv);
10417 // The HTTP request should succeed.
10418 EXPECT_EQ(OK, callback.WaitForResult());
10419
[email protected]eb6234e2012-01-19 01:50:0210420 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210421 ASSERT_TRUE(response);
10422 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210423 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10424
10425 std::string response_data;
10426 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10427 EXPECT_EQ("hello world", response_data);
10428}
10429
[email protected]23e482282013-06-14 16:08:0210430TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc1c196c6e2016-05-28 13:51:4810431 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2ff8b312010-04-26 22:20:5410432
10433 HttpRequestInfo request;
10434 request.method = "GET";
bncce36dca22015-04-21 22:11:2310435 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410436 request.load_flags = 0;
10437
bnc1c196c6e2016-05-28 13:51:4810438 std::string alternative_service_http_header =
10439 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310440
[email protected]2ff8b312010-04-26 22:20:5410441 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210442 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810443 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210444 MockRead("\r\n"),
10445 MockRead("hello world"),
10446 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10447 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410448
10449 StaticSocketDataProvider first_transaction(
10450 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710451 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410452
[email protected]8ddf8322012-02-23 18:08:0610453 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810454 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310455 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10456 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710457 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410458
danakj1fd259a02016-04-16 03:17:0910459 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4910460 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310461 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410462
danakj1fd259a02016-04-16 03:17:0910463 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5510464 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910465 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5510466 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410467 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310468 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410469 };
10470
rch8e6c6c42015-05-01 14:05:1310471 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10472 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710473 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410474
[email protected]d973e99a2012-02-17 21:02:3610475 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510476 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10477 NULL, 0, NULL, 0);
10478 hanging_non_alternate_protocol_socket.set_connect_data(
10479 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710480 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510481 &hanging_non_alternate_protocol_socket);
10482
[email protected]49639fa2011-12-20 23:22:4110483 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410484
danakj1fd259a02016-04-16 03:17:0910485 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10486 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010487 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410488
[email protected]49639fa2011-12-20 23:22:4110489 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410490 EXPECT_EQ(ERR_IO_PENDING, rv);
10491 EXPECT_EQ(OK, callback.WaitForResult());
10492
10493 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210494 ASSERT_TRUE(response);
10495 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410496 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10497
10498 std::string response_data;
10499 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10500 EXPECT_EQ("hello world", response_data);
10501
[email protected]90499482013-06-01 00:39:5010502 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410503
[email protected]49639fa2011-12-20 23:22:4110504 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410505 EXPECT_EQ(ERR_IO_PENDING, rv);
10506 EXPECT_EQ(OK, callback.WaitForResult());
10507
10508 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210509 ASSERT_TRUE(response);
10510 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210511 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310512 EXPECT_TRUE(response->was_fetched_via_spdy);
10513 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410514
10515 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10516 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410517}
10518
[email protected]23e482282013-06-14 16:08:0210519TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc1c196c6e2016-05-28 13:51:4810520 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2d6728692011-03-12 01:39:5510521
10522 HttpRequestInfo request;
10523 request.method = "GET";
bncce36dca22015-04-21 22:11:2310524 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510525 request.load_flags = 0;
10526
bnc1c196c6e2016-05-28 13:51:4810527 std::string alternative_service_http_header =
10528 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310529
[email protected]2d6728692011-03-12 01:39:5510530 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210531 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810532 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210533 MockRead("\r\n"),
10534 MockRead("hello world"),
10535 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10536 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510537 };
10538
10539 StaticSocketDataProvider first_transaction(
10540 data_reads, arraysize(data_reads), NULL, 0);
10541 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:0710542 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510543
[email protected]d973e99a2012-02-17 21:02:3610544 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810545 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10546 hanging_socket1.set_connect_data(never_finishing_connect);
[email protected]2d6728692011-03-12 01:39:5510547 // Socket 2 and 3 are the hanging Alternate-Protocol and
10548 // non-Alternate-Protocol jobs from the 2nd transaction.
mmenkecc2298e2015-12-07 18:20:1810549 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10550
10551 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10552 hanging_socket2.set_connect_data(never_finishing_connect);
10553 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510554
[email protected]8ddf8322012-02-23 18:08:0610555 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810556 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310557 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5210558 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0710559 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510560
danakj1fd259a02016-04-16 03:17:0910561 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4910562 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
danakj1fd259a02016-04-16 03:17:0910563 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4910564 spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:5510565 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310566 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:5510567 };
danakj1fd259a02016-04-16 03:17:0910568 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5510569 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910570 std::unique_ptr<SpdySerializedFrame> data1(
bncb03b1092016-04-06 11:19:5510571 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0910572 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5510573 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0910574 std::unique_ptr<SpdySerializedFrame> data2(
bncb03b1092016-04-06 11:19:5510575 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510576 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310577 CreateMockRead(*resp1, 2),
10578 CreateMockRead(*data1, 3),
10579 CreateMockRead(*resp2, 4),
10580 CreateMockRead(*data2, 5),
10581 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510582 };
10583
rch8e6c6c42015-05-01 14:05:1310584 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10585 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:5510586 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710587 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510588
10589 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
mmenkecc2298e2015-12-07 18:20:1810590 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10591 hanging_socket3.set_connect_data(never_finishing_connect);
10592 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510593
danakj1fd259a02016-04-16 03:17:0910594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110595 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010596 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510597
[email protected]49639fa2011-12-20 23:22:4110598 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510599 EXPECT_EQ(ERR_IO_PENDING, rv);
10600 EXPECT_EQ(OK, callback1.WaitForResult());
10601
10602 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210603 ASSERT_TRUE(response);
10604 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510605 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10606
10607 std::string response_data;
10608 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10609 EXPECT_EQ("hello world", response_data);
10610
[email protected]49639fa2011-12-20 23:22:4110611 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5010612 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110613 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510614 EXPECT_EQ(ERR_IO_PENDING, rv);
10615
[email protected]49639fa2011-12-20 23:22:4110616 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5010617 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110618 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510619 EXPECT_EQ(ERR_IO_PENDING, rv);
10620
10621 EXPECT_EQ(OK, callback2.WaitForResult());
10622 EXPECT_EQ(OK, callback3.WaitForResult());
10623
10624 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5210625 ASSERT_TRUE(response);
10626 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210627 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5510628 EXPECT_TRUE(response->was_fetched_via_spdy);
10629 EXPECT_TRUE(response->was_npn_negotiated);
10630 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10631 EXPECT_EQ("hello!", response_data);
10632
10633 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5210634 ASSERT_TRUE(response);
10635 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210636 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5510637 EXPECT_TRUE(response->was_fetched_via_spdy);
10638 EXPECT_TRUE(response->was_npn_negotiated);
10639 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
10640 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5510641}
10642
bnc1c196c6e2016-05-28 13:51:4810643TEST_P(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
10644 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2d6728692011-03-12 01:39:5510645
10646 HttpRequestInfo request;
10647 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2510648 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510649 request.load_flags = 0;
10650
bnc1c196c6e2016-05-28 13:51:4810651 std::string alternative_service_http_header =
10652 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310653
[email protected]2d6728692011-03-12 01:39:5510654 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210655 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810656 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210657 MockRead("\r\n"),
10658 MockRead("hello world"),
10659 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10660 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510661 };
10662
10663 StaticSocketDataProvider first_transaction(
10664 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710665 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510666
[email protected]8ddf8322012-02-23 18:08:0610667 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810668 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0710669 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510670
[email protected]d973e99a2012-02-17 21:02:3610671 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510672 StaticSocketDataProvider hanging_alternate_protocol_socket(
10673 NULL, 0, NULL, 0);
10674 hanging_alternate_protocol_socket.set_connect_data(
10675 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710676 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510677 &hanging_alternate_protocol_socket);
10678
10679 // 2nd request is just a copy of the first one, over HTTP again.
mmenkecc2298e2015-12-07 18:20:1810680 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
10681 NULL, 0);
10682 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
[email protected]2d6728692011-03-12 01:39:5510683
[email protected]49639fa2011-12-20 23:22:4110684 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5510685
danakj1fd259a02016-04-16 03:17:0910686 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10687 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010688 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510689
[email protected]49639fa2011-12-20 23:22:4110690 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510691 EXPECT_EQ(ERR_IO_PENDING, rv);
10692 EXPECT_EQ(OK, callback.WaitForResult());
10693
10694 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210695 ASSERT_TRUE(response);
10696 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510697 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10698
10699 std::string response_data;
10700 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10701 EXPECT_EQ("hello world", response_data);
10702
[email protected]90499482013-06-01 00:39:5010703 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510704
[email protected]49639fa2011-12-20 23:22:4110705 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510706 EXPECT_EQ(ERR_IO_PENDING, rv);
10707 EXPECT_EQ(OK, callback.WaitForResult());
10708
10709 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210710 ASSERT_TRUE(response);
10711 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510712 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10713 EXPECT_FALSE(response->was_fetched_via_spdy);
10714 EXPECT_FALSE(response->was_npn_negotiated);
10715
10716 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10717 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5510718}
10719
[email protected]631f1322010-04-30 17:59:1110720class CapturingProxyResolver : public ProxyResolver {
10721 public:
sammce90c9212015-05-27 23:43:3510722 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2010723 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1110724
dchengb03027d2014-10-21 12:00:2010725 int GetProxyForURL(const GURL& url,
10726 ProxyInfo* results,
10727 const CompletionCallback& callback,
eroman9c8f4242016-02-29 21:16:5410728 RequestHandle* request,
dchengb03027d2014-10-21 12:00:2010729 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4010730 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
10731 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4210732 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1110733 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4210734 return OK;
[email protected]631f1322010-04-30 17:59:1110735 }
10736
eroman9c8f4242016-02-29 21:16:5410737 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
10738
10739 LoadState GetLoadState(RequestHandle request) const override {
10740 NOTREACHED();
10741 return LOAD_STATE_IDLE;
10742 }
10743
[email protected]24476402010-07-20 20:55:1710744 const std::vector<GURL>& resolved() const { return resolved_; }
10745
10746 private:
[email protected]631f1322010-04-30 17:59:1110747 std::vector<GURL> resolved_;
10748
10749 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
10750};
10751
sammce64b2362015-04-29 03:50:2310752class CapturingProxyResolverFactory : public ProxyResolverFactory {
10753 public:
10754 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
10755 : ProxyResolverFactory(false), resolver_(resolver) {}
10756
10757 int CreateProxyResolver(
10758 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0910759 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2310760 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0910761 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2310762 resolver->reset(new ForwardingProxyResolver(resolver_));
10763 return OK;
10764 }
10765
10766 private:
10767 ProxyResolver* resolver_;
10768};
10769
bnc1c196c6e2016-05-28 13:51:4810770TEST_P(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
10771 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]631f1322010-04-30 17:59:1110772
10773 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4210774 proxy_config.set_auto_detect(true);
10775 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1110776
sammc5dd160c2015-04-02 02:43:1310777 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710778 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0910779 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)),
10780 base::WrapUnique(
sammce64b2362015-04-29 03:50:2310781 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:3810782 NULL));
vishal.b62985ca92015-04-17 08:45:5110783 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710784 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1110785
10786 HttpRequestInfo request;
10787 request.method = "GET";
bncce36dca22015-04-21 22:11:2310788 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:1110789 request.load_flags = 0;
10790
bnc1c196c6e2016-05-28 13:51:4810791 std::string alternative_service_http_header =
10792 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310793
[email protected]631f1322010-04-30 17:59:1110794 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210795 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810796 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210797 MockRead("\r\n"),
10798 MockRead("hello world"),
10799 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10800 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1110801 };
10802
10803 StaticSocketDataProvider first_transaction(
10804 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710805 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1110806
[email protected]8ddf8322012-02-23 18:08:0610807 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810808 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310809 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5210810 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0710811 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1110812
danakj1fd259a02016-04-16 03:17:0910813 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4910814 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1110815 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310816 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2510817 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10818 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1310819 "Proxy-Connection: keep-alive\r\n\r\n"),
10820 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1110821 };
10822
[email protected]d911f1b2010-05-05 22:39:4210823 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10824
danakj1fd259a02016-04-16 03:17:0910825 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5510826 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910827 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5510828 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1110829 MockRead spdy_reads[] = {
mmenkee24011922015-12-17 22:12:5910830 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(*resp.get(), 3),
10831 CreateMockRead(*data.get(), 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1110832 };
10833
rch8e6c6c42015-05-01 14:05:1310834 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10835 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710836 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1110837
[email protected]d973e99a2012-02-17 21:02:3610838 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510839 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10840 NULL, 0, NULL, 0);
10841 hanging_non_alternate_protocol_socket.set_connect_data(
10842 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710843 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510844 &hanging_non_alternate_protocol_socket);
10845
[email protected]49639fa2011-12-20 23:22:4110846 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1110847
danakj1fd259a02016-04-16 03:17:0910848 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10849 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110851
[email protected]49639fa2011-12-20 23:22:4110852 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110853 EXPECT_EQ(ERR_IO_PENDING, rv);
10854 EXPECT_EQ(OK, callback.WaitForResult());
10855
10856 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210857 ASSERT_TRUE(response);
10858 ASSERT_TRUE(response->headers);
[email protected]631f1322010-04-30 17:59:1110859 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310860 EXPECT_FALSE(response->was_fetched_via_spdy);
10861 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110862
10863 std::string response_data;
10864 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10865 EXPECT_EQ("hello world", response_data);
10866
[email protected]90499482013-06-01 00:39:5010867 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110868
[email protected]49639fa2011-12-20 23:22:4110869 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110870 EXPECT_EQ(ERR_IO_PENDING, rv);
10871 EXPECT_EQ(OK, callback.WaitForResult());
10872
10873 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210874 ASSERT_TRUE(response);
10875 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210876 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310877 EXPECT_TRUE(response->was_fetched_via_spdy);
10878 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110879
10880 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10881 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1310882 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2310883 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310884 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2310885 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310886 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1110887
[email protected]029c83b62013-01-24 05:28:2010888 LoadTimingInfo load_timing_info;
10889 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10890 TestLoadTimingNotReusedWithPac(load_timing_info,
10891 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1110892}
[email protected]631f1322010-04-30 17:59:1110893
[email protected]23e482282013-06-14 16:08:0210894TEST_P(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4810895 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
10896 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2ff8b312010-04-26 22:20:5410897
10898 HttpRequestInfo request;
10899 request.method = "GET";
bncce36dca22015-04-21 22:11:2310900 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410901 request.load_flags = 0;
10902
bnc1c196c6e2016-05-28 13:51:4810903 std::string alternative_service_http_header =
10904 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310905
[email protected]2ff8b312010-04-26 22:20:5410906 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210907 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810908 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210909 MockRead("\r\n"),
10910 MockRead("hello world"),
10911 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5410912 };
10913
10914 StaticSocketDataProvider first_transaction(
10915 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710916 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410917
[email protected]8ddf8322012-02-23 18:08:0610918 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810919 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310920 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5210921 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0710922 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410923
danakj1fd259a02016-04-16 03:17:0910924 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4910925 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310926 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410927
danakj1fd259a02016-04-16 03:17:0910928 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5510929 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910930 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5510931 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410932 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310933 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410934 };
10935
rch8e6c6c42015-05-01 14:05:1310936 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10937 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710938 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410939
[email protected]83039bb2011-12-09 18:43:5510940 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410941
danakj1fd259a02016-04-16 03:17:0910942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5410943
danakj1fd259a02016-04-16 03:17:0910944 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010945 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410946
[email protected]49639fa2011-12-20 23:22:4110947 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410948 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110949 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410950
10951 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210952 ASSERT_TRUE(response);
10953 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410954 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10955
10956 std::string response_data;
10957 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10958 EXPECT_EQ("hello world", response_data);
10959
10960 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2510961 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010962 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310963 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710964 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4210965 CreateSecureSpdySession(session.get(), key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3810966
[email protected]90499482013-06-01 00:39:5010967 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410968
[email protected]49639fa2011-12-20 23:22:4110969 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410970 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110971 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410972
10973 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210974 ASSERT_TRUE(response);
10975 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210976 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310977 EXPECT_TRUE(response->was_fetched_via_spdy);
10978 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410979
10980 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10981 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4210982}
10983
[email protected]044de0642010-06-17 10:42:1510984// GenerateAuthToken is a mighty big test.
10985// It tests all permutation of GenerateAuthToken behavior:
10986// - Synchronous and Asynchronous completion.
10987// - OK or error on completion.
10988// - Direct connection, non-authenticating proxy, and authenticating proxy.
10989// - HTTP or HTTPS backend (to include proxy tunneling).
10990// - Non-authenticating and authenticating backend.
10991//
[email protected]fe3b7dc2012-02-03 19:52:0910992// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1510993// problems generating an auth token for an authenticating proxy, we don't
10994// need to test all permutations of the backend server).
10995//
10996// The test proceeds by going over each of the configuration cases, and
10997// potentially running up to three rounds in each of the tests. The TestConfig
10998// specifies both the configuration for the test as well as the expectations
10999// for the results.
[email protected]23e482282013-06-14 16:08:0211000TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011001 static const char kServer[] = "http://www.example.com";
11002 static const char kSecureServer[] = "https://www.example.com";
11003 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511004 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
11005
11006 enum AuthTiming {
11007 AUTH_NONE,
11008 AUTH_SYNC,
11009 AUTH_ASYNC,
11010 };
11011
11012 const MockWrite kGet(
11013 "GET / HTTP/1.1\r\n"
11014 "Host: www.example.com\r\n"
11015 "Connection: keep-alive\r\n\r\n");
11016 const MockWrite kGetProxy(
11017 "GET http://www.example.com/ HTTP/1.1\r\n"
11018 "Host: www.example.com\r\n"
11019 "Proxy-Connection: keep-alive\r\n\r\n");
11020 const MockWrite kGetAuth(
11021 "GET / HTTP/1.1\r\n"
11022 "Host: www.example.com\r\n"
11023 "Connection: keep-alive\r\n"
11024 "Authorization: auth_token\r\n\r\n");
11025 const MockWrite kGetProxyAuth(
11026 "GET http://www.example.com/ HTTP/1.1\r\n"
11027 "Host: www.example.com\r\n"
11028 "Proxy-Connection: keep-alive\r\n"
11029 "Proxy-Authorization: auth_token\r\n\r\n");
11030 const MockWrite kGetAuthThroughProxy(
11031 "GET http://www.example.com/ HTTP/1.1\r\n"
11032 "Host: www.example.com\r\n"
11033 "Proxy-Connection: keep-alive\r\n"
11034 "Authorization: auth_token\r\n\r\n");
11035 const MockWrite kGetAuthWithProxyAuth(
11036 "GET http://www.example.com/ HTTP/1.1\r\n"
11037 "Host: www.example.com\r\n"
11038 "Proxy-Connection: keep-alive\r\n"
11039 "Proxy-Authorization: auth_token\r\n"
11040 "Authorization: auth_token\r\n\r\n");
11041 const MockWrite kConnect(
11042 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711043 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511044 "Proxy-Connection: keep-alive\r\n\r\n");
11045 const MockWrite kConnectProxyAuth(
11046 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711047 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511048 "Proxy-Connection: keep-alive\r\n"
11049 "Proxy-Authorization: auth_token\r\n\r\n");
11050
11051 const MockRead kSuccess(
11052 "HTTP/1.1 200 OK\r\n"
11053 "Content-Type: text/html; charset=iso-8859-1\r\n"
11054 "Content-Length: 3\r\n\r\n"
11055 "Yes");
11056 const MockRead kFailure(
11057 "Should not be called.");
11058 const MockRead kServerChallenge(
11059 "HTTP/1.1 401 Unauthorized\r\n"
11060 "WWW-Authenticate: Mock realm=server\r\n"
11061 "Content-Type: text/html; charset=iso-8859-1\r\n"
11062 "Content-Length: 14\r\n\r\n"
11063 "Unauthorized\r\n");
11064 const MockRead kProxyChallenge(
11065 "HTTP/1.1 407 Unauthorized\r\n"
11066 "Proxy-Authenticate: Mock realm=proxy\r\n"
11067 "Proxy-Connection: close\r\n"
11068 "Content-Type: text/html; charset=iso-8859-1\r\n"
11069 "Content-Length: 14\r\n\r\n"
11070 "Unauthorized\r\n");
11071 const MockRead kProxyConnected(
11072 "HTTP/1.1 200 Connection Established\r\n\r\n");
11073
11074 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11075 // no constructors, but the C++ compiler on Windows warns about
11076 // unspecified data in compound literals. So, moved to using constructors,
11077 // and TestRound's created with the default constructor should not be used.
11078 struct TestRound {
11079 TestRound()
11080 : expected_rv(ERR_UNEXPECTED),
11081 extra_write(NULL),
11082 extra_read(NULL) {
11083 }
11084 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11085 int expected_rv_arg)
11086 : write(write_arg),
11087 read(read_arg),
11088 expected_rv(expected_rv_arg),
11089 extra_write(NULL),
11090 extra_read(NULL) {
11091 }
11092 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11093 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111094 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511095 : write(write_arg),
11096 read(read_arg),
11097 expected_rv(expected_rv_arg),
11098 extra_write(extra_write_arg),
11099 extra_read(extra_read_arg) {
11100 }
11101 MockWrite write;
11102 MockRead read;
11103 int expected_rv;
11104 const MockWrite* extra_write;
11105 const MockRead* extra_read;
11106 };
11107
11108 static const int kNoSSL = 500;
11109
11110 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5111111 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511112 AuthTiming proxy_auth_timing;
11113 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5111114 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511115 AuthTiming server_auth_timing;
11116 int server_auth_rv;
11117 int num_auth_rounds;
11118 int first_ssl_round;
11119 TestRound rounds[3];
11120 } test_configs[] = {
11121 // Non-authenticating HTTP server with a direct connection.
11122 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11123 { TestRound(kGet, kSuccess, OK)}},
11124 // Authenticating HTTP server with a direct connection.
11125 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11126 { TestRound(kGet, kServerChallenge, OK),
11127 TestRound(kGetAuth, kSuccess, OK)}},
11128 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11129 { TestRound(kGet, kServerChallenge, OK),
11130 TestRound(kGetAuth, kFailure, kAuthErr)}},
11131 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11132 { TestRound(kGet, kServerChallenge, OK),
11133 TestRound(kGetAuth, kSuccess, OK)}},
11134 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11135 { TestRound(kGet, kServerChallenge, OK),
11136 TestRound(kGetAuth, kFailure, kAuthErr)}},
11137 // Non-authenticating HTTP server through a non-authenticating proxy.
11138 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11139 { TestRound(kGetProxy, kSuccess, OK)}},
11140 // Authenticating HTTP server through a non-authenticating proxy.
11141 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11142 { TestRound(kGetProxy, kServerChallenge, OK),
11143 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11144 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11145 { TestRound(kGetProxy, kServerChallenge, OK),
11146 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11147 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11148 { TestRound(kGetProxy, kServerChallenge, OK),
11149 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11150 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11151 { TestRound(kGetProxy, kServerChallenge, OK),
11152 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11153 // Non-authenticating HTTP server through an authenticating proxy.
11154 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11155 { TestRound(kGetProxy, kProxyChallenge, OK),
11156 TestRound(kGetProxyAuth, kSuccess, OK)}},
11157 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11158 { TestRound(kGetProxy, kProxyChallenge, OK),
11159 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11160 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11161 { TestRound(kGetProxy, kProxyChallenge, OK),
11162 TestRound(kGetProxyAuth, kSuccess, OK)}},
11163 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11164 { TestRound(kGetProxy, kProxyChallenge, OK),
11165 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11166 // Authenticating HTTP server through an authenticating proxy.
11167 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11168 { TestRound(kGetProxy, kProxyChallenge, OK),
11169 TestRound(kGetProxyAuth, kServerChallenge, OK),
11170 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11171 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11172 { TestRound(kGetProxy, kProxyChallenge, OK),
11173 TestRound(kGetProxyAuth, kServerChallenge, OK),
11174 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11175 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11176 { TestRound(kGetProxy, kProxyChallenge, OK),
11177 TestRound(kGetProxyAuth, kServerChallenge, OK),
11178 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11179 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11180 { TestRound(kGetProxy, kProxyChallenge, OK),
11181 TestRound(kGetProxyAuth, kServerChallenge, OK),
11182 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11183 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11184 { TestRound(kGetProxy, kProxyChallenge, OK),
11185 TestRound(kGetProxyAuth, kServerChallenge, OK),
11186 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11187 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11188 { TestRound(kGetProxy, kProxyChallenge, OK),
11189 TestRound(kGetProxyAuth, kServerChallenge, OK),
11190 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11191 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11192 { TestRound(kGetProxy, kProxyChallenge, OK),
11193 TestRound(kGetProxyAuth, kServerChallenge, OK),
11194 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11195 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11196 { TestRound(kGetProxy, kProxyChallenge, OK),
11197 TestRound(kGetProxyAuth, kServerChallenge, OK),
11198 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11199 // Non-authenticating HTTPS server with a direct connection.
11200 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11201 { TestRound(kGet, kSuccess, OK)}},
11202 // Authenticating HTTPS server with a direct connection.
11203 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11204 { TestRound(kGet, kServerChallenge, OK),
11205 TestRound(kGetAuth, kSuccess, OK)}},
11206 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11207 { TestRound(kGet, kServerChallenge, OK),
11208 TestRound(kGetAuth, kFailure, kAuthErr)}},
11209 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11210 { TestRound(kGet, kServerChallenge, OK),
11211 TestRound(kGetAuth, kSuccess, OK)}},
11212 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11213 { TestRound(kGet, kServerChallenge, OK),
11214 TestRound(kGetAuth, kFailure, kAuthErr)}},
11215 // Non-authenticating HTTPS server with a non-authenticating proxy.
11216 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11217 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11218 // Authenticating HTTPS server through a non-authenticating proxy.
11219 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11220 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11221 TestRound(kGetAuth, kSuccess, OK)}},
11222 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11223 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11224 TestRound(kGetAuth, kFailure, kAuthErr)}},
11225 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11226 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11227 TestRound(kGetAuth, kSuccess, OK)}},
11228 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11229 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11230 TestRound(kGetAuth, kFailure, kAuthErr)}},
11231 // Non-Authenticating HTTPS server through an authenticating proxy.
11232 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11233 { TestRound(kConnect, kProxyChallenge, OK),
11234 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11235 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11236 { TestRound(kConnect, kProxyChallenge, OK),
11237 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11238 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11239 { TestRound(kConnect, kProxyChallenge, OK),
11240 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11241 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11242 { TestRound(kConnect, kProxyChallenge, OK),
11243 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11244 // Authenticating HTTPS server through an authenticating proxy.
11245 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11246 { TestRound(kConnect, kProxyChallenge, OK),
11247 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11248 &kGet, &kServerChallenge),
11249 TestRound(kGetAuth, kSuccess, OK)}},
11250 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11251 { TestRound(kConnect, kProxyChallenge, OK),
11252 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11253 &kGet, &kServerChallenge),
11254 TestRound(kGetAuth, kFailure, kAuthErr)}},
11255 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11256 { TestRound(kConnect, kProxyChallenge, OK),
11257 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11258 &kGet, &kServerChallenge),
11259 TestRound(kGetAuth, kSuccess, OK)}},
11260 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11261 { TestRound(kConnect, kProxyChallenge, OK),
11262 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11263 &kGet, &kServerChallenge),
11264 TestRound(kGetAuth, kFailure, kAuthErr)}},
11265 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11266 { TestRound(kConnect, kProxyChallenge, OK),
11267 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11268 &kGet, &kServerChallenge),
11269 TestRound(kGetAuth, kSuccess, OK)}},
11270 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11271 { TestRound(kConnect, kProxyChallenge, OK),
11272 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11273 &kGet, &kServerChallenge),
11274 TestRound(kGetAuth, kFailure, kAuthErr)}},
11275 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11276 { TestRound(kConnect, kProxyChallenge, OK),
11277 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11278 &kGet, &kServerChallenge),
11279 TestRound(kGetAuth, kSuccess, OK)}},
11280 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11281 { TestRound(kConnect, kProxyChallenge, OK),
11282 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11283 &kGet, &kServerChallenge),
11284 TestRound(kGetAuth, kFailure, kAuthErr)}},
11285 };
11286
viettrungluue4a8b882014-10-16 06:17:3811287 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0811288 HttpAuthHandlerMock::Factory* auth_factory(
11289 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711290 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4911291 SSLInfo empty_ssl_info;
[email protected]044de0642010-06-17 10:42:1511292 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2611293
11294 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1511295 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0811296 for (int n = 0; n < 2; n++) {
11297 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11298 std::string auth_challenge = "Mock realm=proxy";
11299 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2411300 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11301 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0811302 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
asanka5ffd5d72016-03-23 16:20:4911303 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811304 auth_handler->SetGenerateExpectation(
11305 test_config.proxy_auth_timing == AUTH_ASYNC,
11306 test_config.proxy_auth_rv);
11307 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11308 }
[email protected]044de0642010-06-17 10:42:1511309 }
11310 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0011311 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1511312 std::string auth_challenge = "Mock realm=server";
11313 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2411314 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11315 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1511316 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911317 empty_ssl_info, origin, BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511318 auth_handler->SetGenerateExpectation(
11319 test_config.server_auth_timing == AUTH_ASYNC,
11320 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0811321 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1511322 }
11323 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0311324 session_deps_.proxy_service =
11325 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1511326 } else {
rdsmith82957ad2015-09-16 19:42:0311327 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1511328 }
11329
11330 HttpRequestInfo request;
11331 request.method = "GET";
11332 request.url = GURL(test_config.server_url);
11333 request.load_flags = 0;
11334
danakj1fd259a02016-04-16 03:17:0911335 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1511336
rchcb68dc62015-05-21 04:45:3611337 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
11338
11339 std::vector<std::vector<MockRead>> mock_reads(1);
11340 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1511341 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11342 const TestRound& read_write_round = test_config.rounds[round];
11343
11344 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3611345 mock_reads.back().push_back(read_write_round.read);
11346 mock_writes.back().push_back(read_write_round.write);
11347
11348 // kProxyChallenge uses Proxy-Connection: close which means that the
11349 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5411350 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3611351 mock_reads.push_back(std::vector<MockRead>());
11352 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1511353 }
11354
rchcb68dc62015-05-21 04:45:3611355 if (read_write_round.extra_read) {
11356 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1511357 }
rchcb68dc62015-05-21 04:45:3611358 if (read_write_round.extra_write) {
11359 mock_writes.back().push_back(*read_write_round.extra_write);
11360 }
[email protected]044de0642010-06-17 10:42:1511361
11362 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1511363 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0711364 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1511365 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3611366 }
[email protected]044de0642010-06-17 10:42:1511367
danakj1fd259a02016-04-16 03:17:0911368 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3611369 for (size_t i = 0; i < mock_reads.size(); ++i) {
danakj1fd259a02016-04-16 03:17:0911370 data_providers.push_back(base::WrapUnique(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5411371 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3211372 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3611373 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3211374 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3611375 }
11376
mmenkecc2298e2015-12-07 18:20:1811377 // Transaction must be created after DataProviders, so it's destroyed before
11378 // they are as well.
11379 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11380
rchcb68dc62015-05-21 04:45:3611381 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11382 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1511383 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4111384 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1511385 int rv;
11386 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4111387 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511388 } else {
[email protected]49639fa2011-12-20 23:22:4111389 rv = trans.RestartWithAuth(
11390 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1511391 }
11392 if (rv == ERR_IO_PENDING)
11393 rv = callback.WaitForResult();
11394
11395 // Compare results with expected data.
11396 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5011397 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5511398 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1511399 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
11400 continue;
11401 }
11402 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5211403 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511404 } else {
wezca1070932016-05-26 20:30:5211405 EXPECT_FALSE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511406 }
11407 }
[email protected]e5ae96a2010-04-14 20:12:4511408 }
11409}
11410
[email protected]23e482282013-06-14 16:08:0211411TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1411412 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1411413 HttpAuthHandlerMock::Factory* auth_factory(
11414 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711415 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0311416 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0711417 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
11418 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1411419
11420 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11421 auth_handler->set_connection_based(true);
11422 std::string auth_challenge = "Mock realm=server";
11423 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2411424 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11425 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4911426 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1411427 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911428 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811429 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1411430
[email protected]c871bce92010-07-15 21:51:1411431 int rv = OK;
11432 const HttpResponseInfo* response = NULL;
11433 HttpRequestInfo request;
11434 request.method = "GET";
11435 request.url = origin;
11436 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2711437
danakj1fd259a02016-04-16 03:17:0911438 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1011439
11440 // Use a TCP Socket Pool with only one connection per group. This is used
11441 // to validate that the TCP socket is not released to the pool between
11442 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4211443 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2811444 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1011445 50, // Max sockets for pool
11446 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2111447 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
11448 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0911449 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4411450 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0211451 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4811452 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1011453
danakj1fd259a02016-04-16 03:17:0911454 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011455 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111456 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1411457
11458 const MockWrite kGet(
11459 "GET / HTTP/1.1\r\n"
11460 "Host: www.example.com\r\n"
11461 "Connection: keep-alive\r\n\r\n");
11462 const MockWrite kGetAuth(
11463 "GET / HTTP/1.1\r\n"
11464 "Host: www.example.com\r\n"
11465 "Connection: keep-alive\r\n"
11466 "Authorization: auth_token\r\n\r\n");
11467
11468 const MockRead kServerChallenge(
11469 "HTTP/1.1 401 Unauthorized\r\n"
11470 "WWW-Authenticate: Mock realm=server\r\n"
11471 "Content-Type: text/html; charset=iso-8859-1\r\n"
11472 "Content-Length: 14\r\n\r\n"
11473 "Unauthorized\r\n");
11474 const MockRead kSuccess(
11475 "HTTP/1.1 200 OK\r\n"
11476 "Content-Type: text/html; charset=iso-8859-1\r\n"
11477 "Content-Length: 3\r\n\r\n"
11478 "Yes");
11479
11480 MockWrite writes[] = {
11481 // First round
11482 kGet,
11483 // Second round
11484 kGetAuth,
11485 // Third round
11486 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3011487 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1011488 kGetAuth,
11489 // Competing request
11490 kGet,
[email protected]c871bce92010-07-15 21:51:1411491 };
11492 MockRead reads[] = {
11493 // First round
11494 kServerChallenge,
11495 // Second round
11496 kServerChallenge,
11497 // Third round
[email protected]eca50e122010-09-11 14:03:3011498 kServerChallenge,
11499 // Fourth round
[email protected]c871bce92010-07-15 21:51:1411500 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1011501 // Competing response
11502 kSuccess,
[email protected]c871bce92010-07-15 21:51:1411503 };
11504 StaticSocketDataProvider data_provider(reads, arraysize(reads),
11505 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0711506 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1411507
thestig9d3bb0c2015-01-24 00:49:5111508 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1011509
11510 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1411511 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111512 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1411513 if (rv == ERR_IO_PENDING)
11514 rv = callback.WaitForResult();
11515 EXPECT_EQ(OK, rv);
11516 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211517 ASSERT_TRUE(response);
11518 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811519 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411520
[email protected]7ef4cbbb2011-02-06 11:19:1011521 // In between rounds, another request comes in for the same domain.
11522 // It should not be able to grab the TCP socket that trans has already
11523 // claimed.
danakj1fd259a02016-04-16 03:17:0911524 std::unique_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5011525 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111526 TestCompletionCallback callback_compete;
11527 rv = trans_compete->Start(
11528 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1011529 EXPECT_EQ(ERR_IO_PENDING, rv);
11530 // callback_compete.WaitForResult at this point would stall forever,
11531 // since the HttpNetworkTransaction does not release the request back to
11532 // the pool until after authentication completes.
11533
11534 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1411535 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111536 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411537 if (rv == ERR_IO_PENDING)
11538 rv = callback.WaitForResult();
11539 EXPECT_EQ(OK, rv);
11540 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211541 ASSERT_TRUE(response);
11542 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811543 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411544
[email protected]7ef4cbbb2011-02-06 11:19:1011545 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1411546 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111547 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411548 if (rv == ERR_IO_PENDING)
11549 rv = callback.WaitForResult();
11550 EXPECT_EQ(OK, rv);
11551 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211552 ASSERT_TRUE(response);
11553 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811554 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3011555
[email protected]7ef4cbbb2011-02-06 11:19:1011556 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3011557 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111558 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3011559 if (rv == ERR_IO_PENDING)
11560 rv = callback.WaitForResult();
11561 EXPECT_EQ(OK, rv);
11562 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211563 ASSERT_TRUE(response);
11564 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811565 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011566
11567 // Read the body since the fourth round was successful. This will also
11568 // release the socket back to the pool.
11569 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5011570 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011571 if (rv == ERR_IO_PENDING)
11572 rv = callback.WaitForResult();
11573 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011574 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011575 EXPECT_EQ(0, rv);
11576 // There are still 0 idle sockets, since the trans_compete transaction
11577 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2811578 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011579
11580 // The competing request can now finish. Wait for the headers and then
11581 // read the body.
11582 rv = callback_compete.WaitForResult();
11583 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5011584 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011585 if (rv == ERR_IO_PENDING)
11586 rv = callback.WaitForResult();
11587 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011588 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011589 EXPECT_EQ(0, rv);
11590
11591 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2811592 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411593}
11594
[email protected]65041fa2010-05-21 06:56:5311595// This tests the case that a request is issued via http instead of spdy after
11596// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0211597TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bncf33fb31b2016-01-29 15:22:2611598 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d7599122014-05-24 03:37:2311599
[email protected]65041fa2010-05-21 06:56:5311600 HttpRequestInfo request;
11601 request.method = "GET";
bncce36dca22015-04-21 22:11:2311602 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5311603 request.load_flags = 0;
11604
11605 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2311606 MockWrite(
11607 "GET / HTTP/1.1\r\n"
11608 "Host: www.example.org\r\n"
11609 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5311610 };
11611
bnc1c196c6e2016-05-28 13:51:4811612 std::string alternative_service_http_header =
11613 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4311614
[email protected]65041fa2010-05-21 06:56:5311615 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211616 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4811617 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5211618 MockRead("\r\n"),
11619 MockRead("hello world"),
11620 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5311621 };
11622
[email protected]8ddf8322012-02-23 18:08:0611623 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4811624 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5311625
[email protected]bb88e1d32013-05-03 23:11:0711626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5311627
11628 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11629 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711630 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5311631
[email protected]49639fa2011-12-20 23:22:4111632 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5311633
danakj1fd259a02016-04-16 03:17:0911634 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11635 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011636 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5311637
[email protected]49639fa2011-12-20 23:22:4111638 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5311639
11640 EXPECT_EQ(ERR_IO_PENDING, rv);
11641 EXPECT_EQ(OK, callback.WaitForResult());
11642
11643 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211644 ASSERT_TRUE(response);
11645 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5311646 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11647
11648 std::string response_data;
11649 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11650 EXPECT_EQ("hello world", response_data);
11651
11652 EXPECT_FALSE(response->was_fetched_via_spdy);
11653 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5311654}
[email protected]26ef6582010-06-24 02:30:4711655
bnc55ff9da2015-08-19 18:42:3511656// Simulate the SSL handshake completing with an NPN negotiation followed by an
11657// immediate server closing of the socket.
11658// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0211659TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bncf33fb31b2016-01-29 15:22:2611660 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]26ef6582010-06-24 02:30:4711661
11662 HttpRequestInfo request;
11663 request.method = "GET";
bncce36dca22015-04-21 22:11:2311664 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4711665 request.load_flags = 0;
11666
[email protected]8ddf8322012-02-23 18:08:0611667 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811668 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0711669 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4711670
danakj1fd259a02016-04-16 03:17:0911671 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911672 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1311673 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4711674
11675 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611676 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4711677 };
11678
rch8e6c6c42015-05-01 14:05:1311679 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11680 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711681 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4711682
[email protected]49639fa2011-12-20 23:22:4111683 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4711684
danakj1fd259a02016-04-16 03:17:0911685 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11686 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4711688
[email protected]49639fa2011-12-20 23:22:4111689 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4711690 EXPECT_EQ(ERR_IO_PENDING, rv);
11691 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4711692}
[email protected]65d34382010-07-01 18:12:2611693
[email protected]795cbf82013-07-22 09:37:2711694// A subclass of HttpAuthHandlerMock that records the request URL when
11695// it gets it. This is needed since the auth handler may get destroyed
11696// before we get a chance to query it.
11697class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
11698 public:
11699 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
11700
dchengb03027d2014-10-21 12:00:2011701 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2711702
11703 protected:
dchengb03027d2014-10-21 12:00:2011704 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
11705 const HttpRequestInfo* request,
11706 const CompletionCallback& callback,
11707 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2711708 *url_ = request->url;
11709 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
11710 credentials, request, callback, auth_token);
11711 }
11712
11713 private:
11714 GURL* url_;
11715};
11716
bnc55ff9da2015-08-19 18:42:3511717// This test ensures that the URL passed into the proxy is upgraded to https
11718// when doing an Alternate Protocol upgrade.
bnc1c196c6e2016-05-28 13:51:4811719TEST_P(HttpNetworkTransactionTest, SpdyAlternativeServiceThroughProxy) {
bncf33fb31b2016-01-29 15:22:2611720 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]f45c1ee2010-08-03 00:54:3011721
rdsmith82957ad2015-09-16 19:42:0311722 session_deps_.proxy_service =
11723 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111724 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711725 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2711726 GURL request_url;
11727 {
11728 HttpAuthHandlerMock::Factory* auth_factory =
11729 new HttpAuthHandlerMock::Factory();
11730 UrlRecordingHttpAuthHandlerMock* auth_handler =
11731 new UrlRecordingHttpAuthHandlerMock(&request_url);
11732 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11733 auth_factory->set_do_init_from_challenge(true);
11734 session_deps_.http_auth_handler_factory.reset(auth_factory);
11735 }
[email protected]f45c1ee2010-08-03 00:54:3011736
11737 HttpRequestInfo request;
11738 request.method = "GET";
bncce36dca22015-04-21 22:11:2311739 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3011740 request.load_flags = 0;
11741
11742 // First round goes unauthenticated through the proxy.
11743 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2311744 MockWrite(
11745 "GET http://www.example.org/ HTTP/1.1\r\n"
11746 "Host: www.example.org\r\n"
11747 "Proxy-Connection: keep-alive\r\n"
11748 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011749 };
11750 MockRead data_reads_1[] = {
bnc1c196c6e2016-05-28 13:51:4811751 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11752 MockRead("HTTP/1.1 200 OK\r\n"),
11753 MockRead("Alt-Svc: "),
11754 MockRead(GetAlternateProtocolFromParam()),
11755 MockRead("=\":443\"\r\n"),
11756 MockRead("Proxy-Connection: close\r\n"),
11757 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011758 };
11759 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
11760 data_writes_1, arraysize(data_writes_1));
11761
bncce36dca22015-04-21 22:11:2311762 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3011763 // Alternate-Protocol announcement in the first round. It fails due
11764 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2311765 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5911766 // Proxy-Authorization headers. There is then a SPDY request round.
11767 //
[email protected]fe3b7dc2012-02-03 19:52:0911768 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
11769 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
11770 // does a Disconnect and Connect on the same socket, rather than trying
11771 // to obtain a new one.
11772 //
[email protected]394816e92010-08-03 07:38:5911773 // NOTE: Originally, the proxy response to the second CONNECT request
11774 // simply returned another 407 so the unit test could skip the SSL connection
11775 // establishment and SPDY framing issues. Alas, the
11776 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3011777 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5911778
danakj1fd259a02016-04-16 03:17:0911779 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911780 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
danakj1fd259a02016-04-16 03:17:0911781 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5511782 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0911783 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5511784 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3011785
[email protected]394816e92010-08-03 07:38:5911786 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2311787 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311788 MockWrite(ASYNC, 0,
11789 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711790 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311791 "Proxy-Connection: keep-alive\r\n"
11792 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911793
bncce36dca22015-04-21 22:11:2311794 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311795 MockWrite(ASYNC, 2,
11796 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711797 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311798 "Proxy-Connection: keep-alive\r\n"
11799 "Proxy-Authorization: auth_token\r\n"
11800 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011801
bncce36dca22015-04-21 22:11:2311802 // SPDY request
rch8e6c6c42015-05-01 14:05:1311803 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3011804 };
[email protected]394816e92010-08-03 07:38:5911805 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1311806 // First connection attempt fails
mmenkee71e15332015-10-07 16:39:5411807 MockRead(ASYNC, 1,
11808 "HTTP/1.1 407 Unauthorized\r\n"
11809 "Proxy-Authenticate: Mock\r\n"
11810 "Content-Length: 0\r\n"
11811 "Proxy-Connection: keep-alive\r\n"
11812 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911813
rch8e6c6c42015-05-01 14:05:1311814 // Second connection attempt passes
mmenkee71e15332015-10-07 16:39:5411815 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5911816
rch8e6c6c42015-05-01 14:05:1311817 // SPDY response
mmenkee71e15332015-10-07 16:39:5411818 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1311819 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5911820 };
rch8e6c6c42015-05-01 14:05:1311821 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
11822 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3011823
[email protected]8ddf8322012-02-23 18:08:0611824 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811825 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2311826 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5211827 ASSERT_TRUE(ssl.cert);
[email protected]f45c1ee2010-08-03 00:54:3011828
[email protected]d973e99a2012-02-17 21:02:3611829 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511830 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11831 NULL, 0, NULL, 0);
11832 hanging_non_alternate_protocol_socket.set_connect_data(
11833 never_finishing_connect);
11834
[email protected]bb88e1d32013-05-03 23:11:0711835 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
11836 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
11837 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11838 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511839 &hanging_non_alternate_protocol_socket);
danakj1fd259a02016-04-16 03:17:0911840 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3011841
11842 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4111843 TestCompletionCallback callback_1;
danakj1fd259a02016-04-16 03:17:0911844 std::unique_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5011845 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111846 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011847 EXPECT_EQ(ERR_IO_PENDING, rv);
11848 EXPECT_EQ(OK, callback_1.WaitForResult());
11849
11850 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4111851 TestCompletionCallback callback_2;
danakj1fd259a02016-04-16 03:17:0911852 std::unique_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5011853 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111854 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011855 EXPECT_EQ(ERR_IO_PENDING, rv);
11856 EXPECT_EQ(OK, callback_2.WaitForResult());
11857 const HttpResponseInfo* response = trans_2->GetResponseInfo();
wezca1070932016-05-26 20:30:5211858 ASSERT_TRUE(response);
11859 ASSERT_TRUE(response->auth_challenge);
[email protected]f45c1ee2010-08-03 00:54:3011860
11861 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4111862 TestCompletionCallback callback_3;
11863 rv = trans_2->RestartWithAuth(
11864 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3011865 EXPECT_EQ(ERR_IO_PENDING, rv);
11866 EXPECT_EQ(OK, callback_3.WaitForResult());
11867
11868 // After all that work, these two lines (or actually, just the scheme) are
11869 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3011870 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2311871 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3011872
[email protected]029c83b62013-01-24 05:28:2011873 LoadTimingInfo load_timing_info;
11874 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
11875 TestLoadTimingNotReusedWithPac(load_timing_info,
11876 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3811877}
11878
11879// Test that if we cancel the transaction as the connection is completing, that
11880// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0211881TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3811882 // Setup everything about the connection to complete synchronously, so that
11883 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
11884 // for is the callback from the HttpStreamRequest.
11885 // Then cancel the transaction.
11886 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3611887 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3811888 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611889 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
11890 MockRead(SYNCHRONOUS, "hello world"),
11891 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3811892 };
11893
[email protected]8e6441ca2010-08-19 05:56:3811894 HttpRequestInfo request;
11895 request.method = "GET";
bncce36dca22015-04-21 22:11:2311896 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3811897 request.load_flags = 0;
11898
[email protected]bb88e1d32013-05-03 23:11:0711899 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0911900 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11901 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111902 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2711903
[email protected]8e6441ca2010-08-19 05:56:3811904 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11905 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711906 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3811907
[email protected]49639fa2011-12-20 23:22:4111908 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3811909
vishal.b62985ca92015-04-17 08:45:5111910 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4111911 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3811912 EXPECT_EQ(ERR_IO_PENDING, rv);
11913 trans.reset(); // Cancel the transaction here.
11914
[email protected]2da659e2013-05-23 20:51:3411915 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3011916}
11917
[email protected]ecab6e052014-05-16 14:58:1211918// Test that if a transaction is cancelled after receiving the headers, the
11919// stream is drained properly and added back to the socket pool. The main
11920// purpose of this test is to make sure that an HttpStreamParser can be read
11921// from after the HttpNetworkTransaction and the objects it owns have been
11922// deleted.
11923// See http://crbug.com/368418
11924TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
11925 MockRead data_reads[] = {
11926 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
11927 MockRead(ASYNC, "Content-Length: 2\r\n"),
11928 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
11929 MockRead(ASYNC, "1"),
11930 // 2 async reads are necessary to trigger a ReadResponseBody call after the
11931 // HttpNetworkTransaction has been deleted.
11932 MockRead(ASYNC, "2"),
11933 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
11934 };
11935 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11936 session_deps_.socket_factory->AddSocketDataProvider(&data);
11937
danakj1fd259a02016-04-16 03:17:0911938 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1211939
11940 {
11941 HttpRequestInfo request;
11942 request.method = "GET";
bncce36dca22015-04-21 22:11:2311943 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1211944 request.load_flags = 0;
11945
dcheng48459ac22014-08-26 00:46:4111946 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1211947 TestCompletionCallback callback;
11948
11949 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
11950 EXPECT_EQ(ERR_IO_PENDING, rv);
11951 callback.WaitForResult();
11952
11953 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211954 ASSERT_TRUE(response);
11955 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1211956 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11957
11958 // The transaction and HttpRequestInfo are deleted.
11959 }
11960
11961 // Let the HttpResponseBodyDrainer drain the socket.
11962 base::MessageLoop::current()->RunUntilIdle();
11963
11964 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4111965 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1211966}
11967
[email protected]76a505b2010-08-25 06:23:0011968// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211969TEST_P(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0311970 session_deps_.proxy_service =
11971 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111972 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711973 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0911974 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011975
[email protected]76a505b2010-08-25 06:23:0011976 HttpRequestInfo request;
11977 request.method = "GET";
bncce36dca22015-04-21 22:11:2311978 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011979
11980 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311981 MockWrite(
11982 "GET http://www.example.org/ HTTP/1.1\r\n"
11983 "Host: www.example.org\r\n"
11984 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011985 };
11986
11987 MockRead data_reads1[] = {
11988 MockRead("HTTP/1.1 200 OK\r\n"),
11989 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11990 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611991 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011992 };
11993
11994 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11995 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711996 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0011997
[email protected]49639fa2011-12-20 23:22:4111998 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011999
danakj1fd259a02016-04-16 03:17:0912000 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012001 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2712002 BeforeProxyHeadersSentHandler proxy_headers_handler;
12003 trans->SetBeforeProxyHeadersSentCallback(
12004 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
12005 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012006
[email protected]49639fa2011-12-20 23:22:4112007 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012008 EXPECT_EQ(ERR_IO_PENDING, rv);
12009
12010 rv = callback1.WaitForResult();
12011 EXPECT_EQ(OK, rv);
12012
12013 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212014 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012015
12016 EXPECT_TRUE(response->headers->IsKeepAlive());
12017 EXPECT_EQ(200, response->headers->response_code());
12018 EXPECT_EQ(100, response->headers->GetContentLength());
12019 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512020 EXPECT_TRUE(
12021 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2712022 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
12023 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012024 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012025
12026 LoadTimingInfo load_timing_info;
12027 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12028 TestLoadTimingNotReusedWithPac(load_timing_info,
12029 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012030}
12031
12032// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0212033TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312034 session_deps_.proxy_service =
12035 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112036 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712037 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912038 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012039
[email protected]76a505b2010-08-25 06:23:0012040 HttpRequestInfo request;
12041 request.method = "GET";
bncce36dca22015-04-21 22:11:2312042 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012043
12044 // Since we have proxy, should try to establish tunnel.
12045 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712046 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12047 "Host: www.example.org:443\r\n"
12048 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012049
rsleevidb16bb02015-11-12 23:47:1712050 MockWrite("GET / HTTP/1.1\r\n"
12051 "Host: www.example.org\r\n"
12052 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012053 };
12054
12055 MockRead data_reads1[] = {
12056 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12057
12058 MockRead("HTTP/1.1 200 OK\r\n"),
12059 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12060 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612061 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012062 };
12063
12064 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12065 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712066 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612067 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712068 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012069
[email protected]49639fa2011-12-20 23:22:4112070 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012071
danakj1fd259a02016-04-16 03:17:0912072 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012073 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5012074
[email protected]49639fa2011-12-20 23:22:4112075 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012076 EXPECT_EQ(ERR_IO_PENDING, rv);
12077
12078 rv = callback1.WaitForResult();
12079 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4612080 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012081 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012082 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012083 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012084 NetLog::PHASE_NONE);
12085 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012086 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012087 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12088 NetLog::PHASE_NONE);
12089
12090 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212091 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012092
12093 EXPECT_TRUE(response->headers->IsKeepAlive());
12094 EXPECT_EQ(200, response->headers->response_code());
12095 EXPECT_EQ(100, response->headers->GetContentLength());
12096 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12097 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512098 EXPECT_TRUE(
12099 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2012100
12101 LoadTimingInfo load_timing_info;
12102 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12103 TestLoadTimingNotReusedWithPac(load_timing_info,
12104 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012105}
12106
rsleevidb16bb02015-11-12 23:47:1712107// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12108// literal host.
12109TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
12110 session_deps_.proxy_service =
12111 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12112 BoundTestNetLog log;
12113 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912114 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712115
12116 HttpRequestInfo request;
12117 request.method = "GET";
12118 request.url = GURL("https://[::1]:443/");
12119
12120 // Since we have proxy, should try to establish tunnel.
12121 MockWrite data_writes1[] = {
12122 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12123 "Host: [::1]:443\r\n"
12124 "Proxy-Connection: keep-alive\r\n\r\n"),
12125
12126 MockWrite("GET / HTTP/1.1\r\n"
12127 "Host: [::1]\r\n"
12128 "Connection: keep-alive\r\n\r\n"),
12129 };
12130
12131 MockRead data_reads1[] = {
12132 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12133
12134 MockRead("HTTP/1.1 200 OK\r\n"),
12135 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12136 MockRead("Content-Length: 100\r\n\r\n"),
12137 MockRead(SYNCHRONOUS, OK),
12138 };
12139
12140 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12141 data_writes1, arraysize(data_writes1));
12142 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12143 SSLSocketDataProvider ssl(ASYNC, OK);
12144 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12145
12146 TestCompletionCallback callback1;
12147
danakj1fd259a02016-04-16 03:17:0912148 std::unique_ptr<HttpTransaction> trans(
rsleevidb16bb02015-11-12 23:47:1712149 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12150
12151 int rv = trans->Start(&request, callback1.callback(), log.bound());
12152 EXPECT_EQ(ERR_IO_PENDING, rv);
12153
12154 rv = callback1.WaitForResult();
12155 EXPECT_EQ(OK, rv);
12156 TestNetLogEntry::List entries;
12157 log.GetEntries(&entries);
12158 size_t pos = ExpectLogContainsSomewhere(
12159 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12160 NetLog::PHASE_NONE);
12161 ExpectLogContainsSomewhere(
12162 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12163 NetLog::PHASE_NONE);
12164
12165 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212166 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712167
12168 EXPECT_TRUE(response->headers->IsKeepAlive());
12169 EXPECT_EQ(200, response->headers->response_code());
12170 EXPECT_EQ(100, response->headers->GetContentLength());
12171 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12172 EXPECT_TRUE(response->was_fetched_via_proxy);
12173 EXPECT_TRUE(
12174 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
12175
12176 LoadTimingInfo load_timing_info;
12177 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12178 TestLoadTimingNotReusedWithPac(load_timing_info,
12179 CONNECT_TIMING_HAS_SSL_TIMES);
12180}
12181
[email protected]76a505b2010-08-25 06:23:0012182// Test a basic HTTPS GET request through a proxy, but the server hangs up
12183// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0212184TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312185 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112186 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712187 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912188 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012189
[email protected]76a505b2010-08-25 06:23:0012190 HttpRequestInfo request;
12191 request.method = "GET";
bncce36dca22015-04-21 22:11:2312192 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012193
12194 // Since we have proxy, should try to establish tunnel.
12195 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712196 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12197 "Host: www.example.org:443\r\n"
12198 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012199
rsleevidb16bb02015-11-12 23:47:1712200 MockWrite("GET / HTTP/1.1\r\n"
12201 "Host: www.example.org\r\n"
12202 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012203 };
12204
12205 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0612206 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0012207 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612208 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0012209 };
12210
12211 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12212 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712213 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612214 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712215 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012216
[email protected]49639fa2011-12-20 23:22:4112217 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012218
danakj1fd259a02016-04-16 03:17:0912219 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012220 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5012221
[email protected]49639fa2011-12-20 23:22:4112222 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012223 EXPECT_EQ(ERR_IO_PENDING, rv);
12224
12225 rv = callback1.WaitForResult();
12226 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4612227 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012228 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012229 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012230 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012231 NetLog::PHASE_NONE);
12232 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012233 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012234 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12235 NetLog::PHASE_NONE);
12236}
12237
[email protected]749eefa82010-09-13 22:14:0312238// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0212239TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
danakj1fd259a02016-04-16 03:17:0912240 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912241 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1312242 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0312243
danakj1fd259a02016-04-16 03:17:0912244 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5512245 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912246 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5512247 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0312248 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312249 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0312250 };
12251
rch8e6c6c42015-05-01 14:05:1312252 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12253 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712254 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0312255
[email protected]8ddf8322012-02-23 18:08:0612256 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812257 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712258 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0312259
danakj1fd259a02016-04-16 03:17:0912260 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0312261
12262 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2312263 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012264 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312265 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712266 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4212267 CreateInsecureSpdySession(session.get(), key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312268
12269 HttpRequestInfo request;
12270 request.method = "GET";
bncce36dca22015-04-21 22:11:2312271 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0312272 request.load_flags = 0;
12273
12274 // This is the important line that marks this as a preconnect.
12275 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
12276
danakj1fd259a02016-04-16 03:17:0912277 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012278 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0312279
[email protected]41d64e82013-07-03 22:44:2612280 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4112281 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312282 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112283 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0312284}
12285
[email protected]73b8dd222010-11-11 19:55:2412286// Given a net error, cause that error to be returned from the first Write()
12287// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0212288void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0712289 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2912290 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712291 request_info.url = GURL("https://www.example.com/");
12292 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912293 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712294
[email protected]8ddf8322012-02-23 18:08:0612295 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2912296 MockWrite data_writes[] = {
12297 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2412298 };
ttuttle859dc7a2015-04-23 19:42:2912299 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712300 session_deps_.socket_factory->AddSocketDataProvider(&data);
12301 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2412302
danakj1fd259a02016-04-16 03:17:0912303 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12304 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012305 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2412306
[email protected]49639fa2011-12-20 23:22:4112307 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912308 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12309 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2412310 rv = callback.WaitForResult();
12311 ASSERT_EQ(error, rv);
12312}
12313
[email protected]23e482282013-06-14 16:08:0212314TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2412315 // Just check a grab bag of cert errors.
12316 static const int kErrors[] = {
12317 ERR_CERT_COMMON_NAME_INVALID,
12318 ERR_CERT_AUTHORITY_INVALID,
12319 ERR_CERT_DATE_INVALID,
12320 };
12321 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0612322 CheckErrorIsPassedBack(kErrors[i], ASYNC);
12323 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2412324 }
12325}
12326
[email protected]bd0b6772011-01-11 19:59:3012327// Ensure that a client certificate is removed from the SSL client auth
12328// cache when:
12329// 1) No proxy is involved.
12330// 2) TLS False Start is disabled.
12331// 3) The initial TLS handshake requests a client certificate.
12332// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212333TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312334 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912335 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712336 request_info.url = GURL("https://www.example.com/");
12337 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912338 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712339
[email protected]bd0b6772011-01-11 19:59:3012340 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112341 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012342
12343 // [ssl_]data1 contains the data for the first SSL handshake. When a
12344 // CertificateRequest is received for the first time, the handshake will
12345 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2912346 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012347 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712348 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912349 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712350 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012351
12352 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
12353 // False Start is not being used, the result of the SSL handshake will be
12354 // returned as part of the SSLClientSocket::Connect() call. This test
12355 // matches the result of a server sending a handshake_failure alert,
12356 // rather than a Finished message, because it requires a client
12357 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2912358 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012359 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712360 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912361 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712362 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012363
12364 // [ssl_]data3 contains the data for the third SSL handshake. When a
12365 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212366 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
12367 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3012368 // of the HttpNetworkTransaction. Because this test failure is due to
12369 // requiring a client certificate, this fallback handshake should also
12370 // fail.
ttuttle859dc7a2015-04-23 19:42:2912371 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012372 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712373 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912374 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712375 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012376
[email protected]80c75f682012-05-26 16:22:1712377 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
12378 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212379 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
12380 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1712381 // of the HttpNetworkTransaction. Because this test failure is due to
12382 // requiring a client certificate, this fallback handshake should also
12383 // fail.
ttuttle859dc7a2015-04-23 19:42:2912384 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1712385 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712386 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912387 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712388 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712389
danakj1fd259a02016-04-16 03:17:0912390 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12391 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012392 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012393
[email protected]bd0b6772011-01-11 19:59:3012394 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4112395 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912396 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12397 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012398
12399 // Complete the SSL handshake, which should abort due to requiring a
12400 // client certificate.
12401 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912402 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012403
12404 // Indicate that no certificate should be supplied. From the perspective
12405 // of SSLClientCertCache, NULL is just as meaningful as a real
12406 // certificate, so this is the same as supply a
12407 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412408 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912409 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012410
12411 // Ensure the certificate was added to the client auth cache before
12412 // allowing the connection to continue restarting.
12413 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412414 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112415 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412416 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212417 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012418
12419 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712420 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12421 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012422 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912423 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012424
12425 // Ensure that the client certificate is removed from the cache on a
12426 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112427 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412428 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012429}
12430
12431// Ensure that a client certificate is removed from the SSL client auth
12432// cache when:
12433// 1) No proxy is involved.
12434// 2) TLS False Start is enabled.
12435// 3) The initial TLS handshake requests a client certificate.
12436// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212437TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312438 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912439 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712440 request_info.url = GURL("https://www.example.com/");
12441 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912442 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712443
[email protected]bd0b6772011-01-11 19:59:3012444 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112445 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012446
12447 // When TLS False Start is used, SSLClientSocket::Connect() calls will
12448 // return successfully after reading up to the peer's Certificate message.
12449 // This is to allow the caller to call SSLClientSocket::Write(), which can
12450 // enqueue application data to be sent in the same packet as the
12451 // ChangeCipherSpec and Finished messages.
12452 // The actual handshake will be finished when SSLClientSocket::Read() is
12453 // called, which expects to process the peer's ChangeCipherSpec and
12454 // Finished messages. If there was an error negotiating with the peer,
12455 // such as due to the peer requiring a client certificate when none was
12456 // supplied, the alert sent by the peer won't be processed until Read() is
12457 // called.
12458
12459 // Like the non-False Start case, when a client certificate is requested by
12460 // the peer, the handshake is aborted during the Connect() call.
12461 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2912462 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012463 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712464 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912465 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712466 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012467
12468 // When a client certificate is supplied, Connect() will not be aborted
12469 // when the peer requests the certificate. Instead, the handshake will
12470 // artificially succeed, allowing the caller to write the HTTP request to
12471 // the socket. The handshake messages are not processed until Read() is
12472 // called, which then detects that the handshake was aborted, due to the
12473 // peer sending a handshake_failure because it requires a client
12474 // certificate.
ttuttle859dc7a2015-04-23 19:42:2912475 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012476 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712477 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912478 MockRead data2_reads[] = {
12479 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3012480 };
ttuttle859dc7a2015-04-23 19:42:2912481 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712482 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012483
12484 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1712485 // the data for the SSL handshake once the TLSv1.1 connection falls back to
12486 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912487 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012488 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712489 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912490 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712491 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012492
[email protected]80c75f682012-05-26 16:22:1712493 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
12494 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912495 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1712496 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712497 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912498 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712499 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712500
[email protected]7799de12013-05-30 05:52:5112501 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2912502 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5112503 ssl_data5.cert_request_info = cert_request.get();
12504 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2912505 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5112506 session_deps_.socket_factory->AddSocketDataProvider(&data5);
12507
danakj1fd259a02016-04-16 03:17:0912508 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12509 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012510 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012511
[email protected]bd0b6772011-01-11 19:59:3012512 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4112513 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912514 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12515 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012516
12517 // Complete the SSL handshake, which should abort due to requiring a
12518 // client certificate.
12519 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912520 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012521
12522 // Indicate that no certificate should be supplied. From the perspective
12523 // of SSLClientCertCache, NULL is just as meaningful as a real
12524 // certificate, so this is the same as supply a
12525 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412526 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912527 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012528
12529 // Ensure the certificate was added to the client auth cache before
12530 // allowing the connection to continue restarting.
12531 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412532 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112533 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412534 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212535 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012536
[email protected]bd0b6772011-01-11 19:59:3012537 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712538 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12539 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012540 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912541 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012542
12543 // Ensure that the client certificate is removed from the cache on a
12544 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112545 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412546 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012547}
12548
[email protected]8c405132011-01-11 22:03:1812549// Ensure that a client certificate is removed from the SSL client auth
12550// cache when:
12551// 1) An HTTPS proxy is involved.
12552// 3) The HTTPS proxy requests a client certificate.
12553// 4) The client supplies an invalid/unacceptable certificate for the
12554// proxy.
12555// The test is repeated twice, first for connecting to an HTTPS endpoint,
12556// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0212557TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0312558 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5112559 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712560 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1812561
12562 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112563 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1812564
12565 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
12566 // [ssl_]data[1-3]. Rather than represending the endpoint
12567 // (www.example.com:443), they represent failures with the HTTPS proxy
12568 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2912569 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1812570 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712571 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912572 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712573 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1812574
ttuttle859dc7a2015-04-23 19:42:2912575 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812576 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712577 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912578 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712579 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1812580
[email protected]80c75f682012-05-26 16:22:1712581 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
12582#if 0
ttuttle859dc7a2015-04-23 19:42:2912583 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812584 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712585 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912586 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712587 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1712588#endif
[email protected]8c405132011-01-11 22:03:1812589
ttuttle859dc7a2015-04-23 19:42:2912590 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1812591 requests[0].url = GURL("https://www.example.com/");
12592 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912593 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812594
12595 requests[1].url = GURL("http://www.example.com/");
12596 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912597 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812598
12599 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0712600 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0912601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12602 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012603 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1812604
12605 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4112606 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912607 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
12608 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812609
12610 // Complete the SSL handshake, which should abort due to requiring a
12611 // client certificate.
12612 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912613 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1812614
12615 // Indicate that no certificate should be supplied. From the perspective
12616 // of SSLClientCertCache, NULL is just as meaningful as a real
12617 // certificate, so this is the same as supply a
12618 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412619 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912620 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812621
12622 // Ensure the certificate was added to the client auth cache before
12623 // allowing the connection to continue restarting.
12624 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412625 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112626 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412627 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212628 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1812629 // Ensure the certificate was NOT cached for the endpoint. This only
12630 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4112631 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412632 HostPortPair("www.example.com", 443), &client_cert,
12633 &client_private_key));
[email protected]8c405132011-01-11 22:03:1812634
12635 // Restart the handshake. This will consume ssl_data2, which fails, and
12636 // then consume ssl_data3, which should also fail. The result code is
12637 // checked against what ssl_data3 should return.
12638 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912639 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1812640
12641 // Now that the new handshake has failed, ensure that the client
12642 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4112643 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412644 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4112645 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412646 HostPortPair("www.example.com", 443), &client_cert,
12647 &client_private_key));
[email protected]8c405132011-01-11 22:03:1812648 }
12649}
12650
mmenke5c642132015-06-02 16:05:1312651TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bncf33fb31b2016-01-29 15:22:2612652 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4612653
12654 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712655 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0912656 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612657 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12658 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612659
[email protected]8ddf8322012-02-23 18:08:0612660 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812661 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712662 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612663
danakj1fd259a02016-04-16 03:17:0912664 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4912665 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812666 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0912667 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4912668 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612669 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312670 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612671 };
danakj1fd259a02016-04-16 03:17:0912672 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0212673 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912674 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0212675 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0912676 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0212677 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0912678 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0212679 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612680 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312681 CreateMockRead(*host1_resp, 1),
12682 CreateMockRead(*host1_resp_body, 2),
12683 CreateMockRead(*host2_resp, 4),
12684 CreateMockRead(*host2_resp_body, 5),
12685 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612686 };
12687
eroman36d84e54432016-03-17 03:23:0212688 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0212689 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312690 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12691 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712692 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612693
[email protected]aa22b242011-11-16 18:58:2912694 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612695 HttpRequestInfo request1;
12696 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312697 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612698 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012699 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612700
[email protected]49639fa2011-12-20 23:22:4112701 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612702 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112703 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612704
12705 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212706 ASSERT_TRUE(response);
12707 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212708 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612709
12710 std::string response_data;
12711 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12712 EXPECT_EQ("hello!", response_data);
12713
12714 // Preload www.gmail.com into HostCache.
12715 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1012716 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4612717 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012718 rv = session_deps_.host_resolver->Resolve(resolve_info,
12719 DEFAULT_PRIORITY,
12720 &ignored,
12721 callback.callback(),
12722 NULL,
12723 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712724 EXPECT_EQ(ERR_IO_PENDING, rv);
12725 rv = callback.WaitForResult();
12726 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612727
12728 HttpRequestInfo request2;
12729 request2.method = "GET";
12730 request2.url = GURL("https://www.gmail.com/");
12731 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012732 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612733
[email protected]49639fa2011-12-20 23:22:4112734 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612735 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112736 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612737
12738 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212739 ASSERT_TRUE(response);
12740 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212741 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612742 EXPECT_TRUE(response->was_fetched_via_spdy);
12743 EXPECT_TRUE(response->was_npn_negotiated);
12744 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12745 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612746}
12747
[email protected]23e482282013-06-14 16:08:0212748TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bncf33fb31b2016-01-29 15:22:2612749 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d2b5f092012-06-08 23:55:0212750
12751 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712752 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0912753 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0212754 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12755 pool_peer.DisableDomainAuthenticationVerification();
12756
12757 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812758 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0212760
danakj1fd259a02016-04-16 03:17:0912761 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4912762 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812763 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0912764 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4912765 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0212766 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312767 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0212768 };
danakj1fd259a02016-04-16 03:17:0912769 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0212770 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912771 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0212772 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0912773 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0212774 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0912775 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0212776 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0212777 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312778 CreateMockRead(*host1_resp, 1),
12779 CreateMockRead(*host1_resp_body, 2),
12780 CreateMockRead(*host2_resp, 4),
12781 CreateMockRead(*host2_resp_body, 5),
12782 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0212783 };
12784
eroman36d84e54432016-03-17 03:23:0212785 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0212786 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312787 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12788 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712789 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0212790
12791 TestCompletionCallback callback;
12792 HttpRequestInfo request1;
12793 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312794 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0212795 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012796 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212797
12798 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
12799 EXPECT_EQ(ERR_IO_PENDING, rv);
12800 EXPECT_EQ(OK, callback.WaitForResult());
12801
12802 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212803 ASSERT_TRUE(response);
12804 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212805 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0212806
12807 std::string response_data;
12808 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12809 EXPECT_EQ("hello!", response_data);
12810
12811 HttpRequestInfo request2;
12812 request2.method = "GET";
12813 request2.url = GURL("https://www.gmail.com/");
12814 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012815 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212816
12817 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
12818 EXPECT_EQ(ERR_IO_PENDING, rv);
12819 EXPECT_EQ(OK, callback.WaitForResult());
12820
12821 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212822 ASSERT_TRUE(response);
12823 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212824 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0212825 EXPECT_TRUE(response->was_fetched_via_spdy);
12826 EXPECT_TRUE(response->was_npn_negotiated);
12827 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12828 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0212829}
12830
ttuttle859dc7a2015-04-23 19:42:2912831class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4612832 public:
12833 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
12834 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2012835 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4612836
12837 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
12838
12839 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2012840 int Resolve(const RequestInfo& info,
12841 RequestPriority priority,
12842 AddressList* addresses,
12843 const CompletionCallback& callback,
12844 RequestHandle* out_req,
12845 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012846 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1012847 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4012848 }
12849
dchengb03027d2014-10-21 12:00:2012850 int ResolveFromCache(const RequestInfo& info,
12851 AddressList* addresses,
12852 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012853 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
12854 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0912855 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4612856 return rv;
12857 }
12858
dchengb03027d2014-10-21 12:00:2012859 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4612860 host_resolver_.CancelRequest(req);
12861 }
12862
[email protected]46da33be2011-07-19 21:58:0412863 MockCachingHostResolver* GetMockHostResolver() {
12864 return &host_resolver_;
12865 }
12866
[email protected]e3ceb682011-06-28 23:55:4612867 private:
12868 MockCachingHostResolver host_resolver_;
12869 const HostPortPair host_port_;
12870};
12871
mmenke5c642132015-06-02 16:05:1312872TEST_P(HttpNetworkTransactionTest,
12873 UseIPConnectionPoolingWithHostCacheExpiration) {
bncf33fb31b2016-01-29 15:22:2612874 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4612875
12876 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4612877 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3412878 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0712879 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4612880 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0912881 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612882 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12883 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612884
[email protected]8ddf8322012-02-23 18:08:0612885 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812886 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712887 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612888
danakj1fd259a02016-04-16 03:17:0912889 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4912890 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812891 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0912892 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4912893 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612894 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312895 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612896 };
danakj1fd259a02016-04-16 03:17:0912897 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0212898 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912899 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0212900 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0912901 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0212902 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0912903 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0212904 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612905 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312906 CreateMockRead(*host1_resp, 1),
12907 CreateMockRead(*host1_resp_body, 2),
12908 CreateMockRead(*host2_resp, 4),
12909 CreateMockRead(*host2_resp_body, 5),
12910 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612911 };
12912
eroman36d84e54432016-03-17 03:23:0212913 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0212914 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312915 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12916 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712917 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612918
[email protected]aa22b242011-11-16 18:58:2912919 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612920 HttpRequestInfo request1;
12921 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312922 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612923 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012924 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612925
[email protected]49639fa2011-12-20 23:22:4112926 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612927 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112928 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612929
12930 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212931 ASSERT_TRUE(response);
12932 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212933 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612934
12935 std::string response_data;
12936 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12937 EXPECT_EQ("hello!", response_data);
12938
12939 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1012940 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4612941 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012942 rv = host_resolver.Resolve(resolve_info,
12943 DEFAULT_PRIORITY,
12944 &ignored,
12945 callback.callback(),
12946 NULL,
12947 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712948 EXPECT_EQ(ERR_IO_PENDING, rv);
12949 rv = callback.WaitForResult();
12950 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612951
12952 HttpRequestInfo request2;
12953 request2.method = "GET";
12954 request2.url = GURL("https://www.gmail.com/");
12955 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012956 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612957
[email protected]49639fa2011-12-20 23:22:4112958 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612959 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112960 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612961
12962 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212963 ASSERT_TRUE(response);
12964 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212965 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612966 EXPECT_TRUE(response->was_fetched_via_spdy);
12967 EXPECT_TRUE(response->was_npn_negotiated);
12968 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12969 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612970}
12971
[email protected]23e482282013-06-14 16:08:0212972TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2312973 const std::string https_url = "https://www.example.org:8080/";
12974 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412975
12976 // SPDY GET for HTTPS URL
danakj1fd259a02016-04-16 03:17:0912977 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4912978 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0412979
12980 MockWrite writes1[] = {
12981 CreateMockWrite(*req1, 0),
12982 };
12983
danakj1fd259a02016-04-16 03:17:0912984 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5512985 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912986 std::unique_ptr<SpdySerializedFrame> body1(
bncb03b1092016-04-06 11:19:5512987 spdy_util_.ConstructSpdyBodyFrame(1, true));
mmenkee24011922015-12-17 22:12:5912988 MockRead reads1[] = {CreateMockRead(*resp1, 1), CreateMockRead(*body1, 2),
12989 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0412990
rch8e6c6c42015-05-01 14:05:1312991 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
12992 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412993 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712994 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412995
12996 // HTTP GET for the HTTP URL
12997 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1312998 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3412999 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313000 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413001 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413002 };
13003
13004 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313005 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13006 MockRead(ASYNC, 2, "hello"),
13007 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413008 };
13009
rch8e6c6c42015-05-01 14:05:1313010 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13011 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413012
[email protected]8450d722012-07-02 19:14:0413013 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813014 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713015 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13016 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13017 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413018
danakj1fd259a02016-04-16 03:17:0913019 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413020
13021 // Start the first transaction to set up the SpdySession
13022 HttpRequestInfo request1;
13023 request1.method = "GET";
13024 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413025 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013026 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413027 TestCompletionCallback callback1;
13028 EXPECT_EQ(ERR_IO_PENDING,
13029 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413030 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413031
13032 EXPECT_EQ(OK, callback1.WaitForResult());
13033 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13034
13035 // Now, start the HTTP request
13036 HttpRequestInfo request2;
13037 request2.method = "GET";
13038 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413039 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013040 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413041 TestCompletionCallback callback2;
13042 EXPECT_EQ(ERR_IO_PENDING,
13043 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413044 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413045
13046 EXPECT_EQ(OK, callback2.WaitForResult());
13047 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13048}
13049
bnc1b0e36852015-04-28 15:32:5913050class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
13051 public:
13052 void Run(bool pooling, bool valid) {
zhongyi3d4a55e72016-04-22 20:36:4613053 url::SchemeHostPort server(GURL(valid ? "https://mail.example.org:443"
13054 : "https://invalid.example.org:443"));
bnc1b0e36852015-04-28 15:32:5913055 HostPortPair alternative("www.example.org", 443);
13056
13057 base::FilePath certs_dir = GetTestCertsDirectory();
13058 scoped_refptr<X509Certificate> cert(
13059 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
wezca1070932016-05-26 20:30:5213060 ASSERT_TRUE(cert);
bnc1b0e36852015-04-28 15:32:5913061 bool common_name_fallback_used;
13062 EXPECT_EQ(valid,
zhongyi3d4a55e72016-04-22 20:36:4613063 cert->VerifyNameMatch(server.host(), &common_name_fallback_used));
bnc1b0e36852015-04-28 15:32:5913064 EXPECT_TRUE(
13065 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
13066 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813067 ssl.SetNextProto(GetProtocol());
bnc1b0e36852015-04-28 15:32:5913068 ssl.cert = cert;
13069 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13070
13071 // If pooling, then start a request to alternative first to create a
13072 // SpdySession.
13073 std::string url0 = "https://www.example.org:443";
zhongyi3d4a55e72016-04-22 20:36:4613074 // Second request to server, which has an alternative service, and could
bnc1b0e36852015-04-28 15:32:5913075 // open a connection to the alternative host or pool to the existing one.
13076 std::string url1("https://");
zhongyi3d4a55e72016-04-22 20:36:4613077 url1.append(server.host());
bnc1b0e36852015-04-28 15:32:5913078 url1.append(":443");
13079
danakj1fd259a02016-04-16 03:17:0913080 std::unique_ptr<SpdySerializedFrame> req0;
13081 std::unique_ptr<SpdySerializedFrame> req1;
13082 std::unique_ptr<SpdySerializedFrame> resp0;
13083 std::unique_ptr<SpdySerializedFrame> body0;
13084 std::unique_ptr<SpdySerializedFrame> resp1;
13085 std::unique_ptr<SpdySerializedFrame> body1;
bnc1b0e36852015-04-28 15:32:5913086 std::vector<MockWrite> writes;
13087 std::vector<MockRead> reads;
13088
13089 if (pooling) {
bnc38dcd392016-02-09 23:19:4913090 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813091 spdy_util_.UpdateWithStreamDestruction(1);
bnc38dcd392016-02-09 23:19:4913092 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 3, LOWEST));
bnc1b0e36852015-04-28 15:32:5913093
13094 writes.push_back(CreateMockWrite(*req0, 0));
13095 writes.push_back(CreateMockWrite(*req1, 3));
13096
13097 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13098 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13099 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
13100 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
13101
13102 reads.push_back(CreateMockRead(*resp0, 1));
13103 reads.push_back(CreateMockRead(*body0, 2));
13104 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
13105 reads.push_back(CreateMockRead(*resp1, 5));
13106 reads.push_back(CreateMockRead(*body1, 6));
13107 reads.push_back(MockRead(ASYNC, OK, 7));
13108 } else {
bnc38dcd392016-02-09 23:19:4913109 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 1, LOWEST));
bnc1b0e36852015-04-28 15:32:5913110
13111 writes.push_back(CreateMockWrite(*req1, 0));
13112
13113 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13114 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13115
13116 reads.push_back(CreateMockRead(*resp1, 1));
13117 reads.push_back(CreateMockRead(*body1, 2));
13118 reads.push_back(MockRead(ASYNC, OK, 3));
13119 }
13120
davidben5f8b6bc2015-11-25 03:19:5413121 SequencedSocketData data(reads.data(), reads.size(), writes.data(),
13122 writes.size());
bnc1b0e36852015-04-28 15:32:5913123 session_deps_.socket_factory->AddSocketDataProvider(&data);
13124
zhongyi3d4a55e72016-04-22 20:36:4613125 // Connection to the server fails.
bnc1b0e36852015-04-28 15:32:5913126 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13127 StaticSocketDataProvider data_refused;
13128 data_refused.set_connect_data(mock_connect);
13129 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13130
bncf33fb31b2016-01-29 15:22:2613131 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913132 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc1b0e36852015-04-28 15:32:5913133 base::WeakPtr<HttpServerProperties> http_server_properties =
13134 session->http_server_properties();
13135 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813136 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213137 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613138 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013139 expiration);
bnc1b0e36852015-04-28 15:32:5913140
13141 // First request to alternative.
13142 if (pooling) {
danakj1fd259a02016-04-16 03:17:0913143 std::unique_ptr<HttpTransaction> trans0(
bnc1b0e36852015-04-28 15:32:5913144 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13145 HttpRequestInfo request0;
13146 request0.method = "GET";
13147 request0.url = GURL(url0);
13148 request0.load_flags = 0;
13149 TestCompletionCallback callback0;
13150
13151 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
13152 EXPECT_EQ(ERR_IO_PENDING, rv);
13153 rv = callback0.WaitForResult();
13154 EXPECT_EQ(OK, rv);
13155 }
13156
13157 // Second request to origin.
danakj1fd259a02016-04-16 03:17:0913158 std::unique_ptr<HttpTransaction> trans1(
bnc1b0e36852015-04-28 15:32:5913159 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13160 HttpRequestInfo request1;
13161 request1.method = "GET";
13162 request1.url = GURL(url1);
13163 request1.load_flags = 0;
13164 TestCompletionCallback callback1;
13165
13166 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13167 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0913168 base::MessageLoop::current()->RunUntilIdle();
mmenkee24011922015-12-17 22:12:5913169 if (data.IsPaused())
13170 data.Resume();
bnc1b0e36852015-04-28 15:32:5913171 rv = callback1.WaitForResult();
13172 if (valid) {
13173 EXPECT_EQ(OK, rv);
13174 } else {
13175 if (pooling) {
13176 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13177 } else {
13178 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
13179 }
13180 }
13181 }
13182};
13183
rdsmithebb50aa2015-11-12 03:44:3813184INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc1b0e36852015-04-28 15:32:5913185 AltSvcCertificateVerificationTest,
rdsmithebb50aa2015-11-12 03:44:3813186 testing::Values(kTestCaseSPDY31,
13187 kTestCaseHTTP2NoPriorityDependencies,
13188 kTestCaseHTTP2PriorityDependencies));
bnc1b0e36852015-04-28 15:32:5913189
13190// The alternative service host must exhibit a certificate that is valid for the
13191// origin host. Test that this is enforced when pooling to an existing
13192// connection.
13193TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
13194 Run(true, true);
13195}
13196
13197TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
13198 Run(true, false);
13199}
13200
13201// The alternative service host must exhibit a certificate that is valid for the
13202// origin host. Test that this is enforced when opening a new connection.
13203TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
13204 Run(false, true);
13205}
13206
bnc8bef8da22016-05-30 01:28:2513207// TODO(bnc): Re-enable when https://crbug.com/615413 is fixed.
13208TEST_P(AltSvcCertificateVerificationTest, DISABLED_NewConnectionInvalid) {
bnc1b0e36852015-04-28 15:32:5913209 Run(false, false);
13210}
13211
bnc5452e2a2015-05-08 16:27:4213212// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13213// with the alternative server. That connection should not be used.
13214TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2513215 url::SchemeHostPort server("https", "www.example.org", 443);
13216 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4213217
bnc8bef8da22016-05-30 01:28:2513218 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4213219 SSLSocketDataProvider ssl(ASYNC, OK);
13220 ssl.SetNextProto(kProtoHTTP11);
13221 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13222
13223 // No data should be read from the alternative, because HTTP/1.1 is
13224 // negotiated.
13225 StaticSocketDataProvider data;
13226 session_deps_.socket_factory->AddSocketDataProvider(&data);
13227
13228 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4613229 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4213230 // mocked. This way the request relies on the alternate Job.
13231 StaticSocketDataProvider data_refused;
13232 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13233 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13234
zhongyi3d4a55e72016-04-22 20:36:4613235 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613236 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913237 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213238 base::WeakPtr<HttpServerProperties> http_server_properties =
13239 session->http_server_properties();
13240 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813241 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213242 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613243 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013244 expiration);
bnc5452e2a2015-05-08 16:27:4213245
danakj1fd259a02016-04-16 03:17:0913246 std::unique_ptr<HttpTransaction> trans(
bnc5452e2a2015-05-08 16:27:4213247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13248 HttpRequestInfo request;
13249 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2513250 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4213251 request.load_flags = 0;
13252 TestCompletionCallback callback;
13253
13254 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
13255 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
13256 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13257 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
13258}
13259
bnc40448a532015-05-11 19:13:1413260// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4613261// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1413262// succeeds, the request should succeed, even if the latter fails because
13263// HTTP/1.1 is negotiated which is insufficient for alternative service.
13264TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2513265 url::SchemeHostPort server("https", "www.example.org", 443);
13266 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1413267
13268 // Negotiate HTTP/1.1 with alternative.
13269 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
13270 alternative_ssl.SetNextProto(kProtoHTTP11);
13271 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13272
13273 // No data should be read from the alternative, because HTTP/1.1 is
13274 // negotiated.
13275 StaticSocketDataProvider data;
13276 session_deps_.socket_factory->AddSocketDataProvider(&data);
13277
zhongyi3d4a55e72016-04-22 20:36:4613278 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1413279 SSLSocketDataProvider origin_ssl(ASYNC, OK);
13280 origin_ssl.SetNextProto(kProtoHTTP11);
13281 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13282
13283 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2513284 MockWrite("GET / HTTP/1.1\r\n"
13285 "Host: www.example.org\r\n"
13286 "Connection: keep-alive\r\n\r\n"),
13287 MockWrite("GET /second HTTP/1.1\r\n"
13288 "Host: www.example.org\r\n"
13289 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1413290 };
13291
13292 MockRead http_reads[] = {
13293 MockRead("HTTP/1.1 200 OK\r\n"),
13294 MockRead("Content-Type: text/html\r\n"),
13295 MockRead("Content-Length: 6\r\n\r\n"),
13296 MockRead("foobar"),
13297 MockRead("HTTP/1.1 200 OK\r\n"),
13298 MockRead("Content-Type: text/html\r\n"),
13299 MockRead("Content-Length: 7\r\n\r\n"),
13300 MockRead("another"),
13301 };
13302 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13303 http_writes, arraysize(http_writes));
13304 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13305
zhongyi3d4a55e72016-04-22 20:36:4613306 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613307 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc40448a532015-05-11 19:13:1413309 base::WeakPtr<HttpServerProperties> http_server_properties =
13310 session->http_server_properties();
13311 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813312 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213313 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613314 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013315 expiration);
bnc40448a532015-05-11 19:13:1413316
13317 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13318 HttpRequestInfo request1;
13319 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2513320 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1413321 request1.load_flags = 0;
13322 TestCompletionCallback callback1;
13323
13324 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
13325 rv = callback1.GetResult(rv);
13326 EXPECT_EQ(OK, rv);
13327
13328 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213329 ASSERT_TRUE(response1);
13330 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1413331 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13332
13333 std::string response_data1;
13334 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
13335 EXPECT_EQ("foobar", response_data1);
13336
13337 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13338 // for alternative service.
13339 EXPECT_TRUE(
13340 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13341
zhongyi3d4a55e72016-04-22 20:36:4613342 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1413343 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4613344 // to server.
bnc40448a532015-05-11 19:13:1413345 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13346 HttpRequestInfo request2;
13347 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2513348 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1413349 request2.load_flags = 0;
13350 TestCompletionCallback callback2;
13351
13352 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
13353 rv = callback2.GetResult(rv);
13354 EXPECT_EQ(OK, rv);
13355
13356 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213357 ASSERT_TRUE(response2);
13358 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1413359 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13360
13361 std::string response_data2;
13362 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
13363 EXPECT_EQ("another", response_data2);
13364}
13365
bnc5452e2a2015-05-08 16:27:4213366// Alternative service requires HTTP/2 (or SPDY), but there is already a
13367// HTTP/1.1 socket open to the alternative server. That socket should not be
13368// used.
13369TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4613370 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4213371 HostPortPair alternative("alternative.example.org", 443);
13372 std::string origin_url = "https://origin.example.org:443";
13373 std::string alternative_url = "https://alternative.example.org:443";
13374
13375 // Negotiate HTTP/1.1 with alternative.example.org.
13376 SSLSocketDataProvider ssl(ASYNC, OK);
13377 ssl.SetNextProto(kProtoHTTP11);
13378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13379
13380 // HTTP/1.1 data for |request1| and |request2|.
13381 MockWrite http_writes[] = {
13382 MockWrite(
13383 "GET / HTTP/1.1\r\n"
13384 "Host: alternative.example.org\r\n"
13385 "Connection: keep-alive\r\n\r\n"),
13386 MockWrite(
13387 "GET / HTTP/1.1\r\n"
13388 "Host: alternative.example.org\r\n"
13389 "Connection: keep-alive\r\n\r\n"),
13390 };
13391
13392 MockRead http_reads[] = {
13393 MockRead(
13394 "HTTP/1.1 200 OK\r\n"
13395 "Content-Type: text/html; charset=iso-8859-1\r\n"
13396 "Content-Length: 40\r\n\r\n"
13397 "first HTTP/1.1 response from alternative"),
13398 MockRead(
13399 "HTTP/1.1 200 OK\r\n"
13400 "Content-Type: text/html; charset=iso-8859-1\r\n"
13401 "Content-Length: 41\r\n\r\n"
13402 "second HTTP/1.1 response from alternative"),
13403 };
13404 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13405 http_writes, arraysize(http_writes));
13406 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13407
13408 // This test documents that an alternate Job should not pool to an already
13409 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4613410 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4213411 StaticSocketDataProvider data_refused;
13412 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13413 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13414
zhongyi3d4a55e72016-04-22 20:36:4613415 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613416 session_deps_.enable_alternative_service_with_different_host = false;
danakj1fd259a02016-04-16 03:17:0913417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213418 base::WeakPtr<HttpServerProperties> http_server_properties =
13419 session->http_server_properties();
13420 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813421 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213422 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613423 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013424 expiration);
bnc5452e2a2015-05-08 16:27:4213425
13426 // First transaction to alternative to open an HTTP/1.1 socket.
danakj1fd259a02016-04-16 03:17:0913427 std::unique_ptr<HttpTransaction> trans1(
bnc5452e2a2015-05-08 16:27:4213428 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13429 HttpRequestInfo request1;
13430 request1.method = "GET";
13431 request1.url = GURL(alternative_url);
13432 request1.load_flags = 0;
13433 TestCompletionCallback callback1;
13434
13435 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13436 EXPECT_EQ(OK, callback1.GetResult(rv));
13437 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13438 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5213439 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4213440 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13441 EXPECT_TRUE(response1->was_npn_negotiated);
13442 EXPECT_FALSE(response1->was_fetched_via_spdy);
13443 std::string response_data1;
13444 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
13445 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
13446
13447 // Request for origin.example.org, which has an alternative service. This
13448 // will start two Jobs: the alternative looks for connections to pool to,
13449 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4613450 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4213451 // this request fails.
danakj1fd259a02016-04-16 03:17:0913452 std::unique_ptr<HttpTransaction> trans2(
bnc5452e2a2015-05-08 16:27:4213453 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13454 HttpRequestInfo request2;
13455 request2.method = "GET";
13456 request2.url = GURL(origin_url);
13457 request2.load_flags = 0;
13458 TestCompletionCallback callback2;
13459
13460 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
13461 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
13462
13463 // Another transaction to alternative. This is to test that the HTTP/1.1
13464 // socket is still open and in the pool.
danakj1fd259a02016-04-16 03:17:0913465 std::unique_ptr<HttpTransaction> trans3(
bnc5452e2a2015-05-08 16:27:4213466 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13467 HttpRequestInfo request3;
13468 request3.method = "GET";
13469 request3.url = GURL(alternative_url);
13470 request3.load_flags = 0;
13471 TestCompletionCallback callback3;
13472
13473 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
13474 EXPECT_EQ(OK, callback3.GetResult(rv));
13475 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
13476 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5213477 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4213478 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
13479 EXPECT_TRUE(response3->was_npn_negotiated);
13480 EXPECT_FALSE(response3->was_fetched_via_spdy);
13481 std::string response_data3;
13482 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
13483 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
13484}
13485
[email protected]23e482282013-06-14 16:08:0213486TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2313487 const std::string https_url = "https://www.example.org:8080/";
13488 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413489
rdsmithebb50aa2015-11-12 03:44:3813490 // Separate SPDY util instance for naked and wrapped requests.
13491 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
13492
[email protected]8450d722012-07-02 19:14:0413493 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2313494 const HostPortPair host_port_pair("www.example.org", 8080);
danakj1fd259a02016-04-16 03:17:0913495 std::unique_ptr<SpdySerializedFrame> connect(
lgarrona91df87f2014-12-05 00:51:3413496 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
danakj1fd259a02016-04-16 03:17:0913497 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913498 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
danakj1fd259a02016-04-16 03:17:0913499 std::unique_ptr<SpdySerializedFrame> wrapped_req1(
[email protected]23e482282013-06-14 16:08:0213500 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3913501
13502 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2913503 SpdyHeaderBlock req2_block;
bnc7ecc1122015-09-28 13:22:4913504 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]745aa9c2014-06-27 02:21:2913505 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2313506 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2913507 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4913508 req2_block[spdy_util_.GetPathKey()] = "/";
danakj1fd259a02016-04-16 03:17:0913509 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913510 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0413511
13512 MockWrite writes1[] = {
mmenke666a6fea2015-12-19 04:16:3313513 CreateMockWrite(*connect, 0), CreateMockWrite(*wrapped_req1, 2),
13514 CreateMockWrite(*req2, 6),
[email protected]8450d722012-07-02 19:14:0413515 };
13516
danakj1fd259a02016-04-16 03:17:0913517 std::unique_ptr<SpdySerializedFrame> conn_resp(
bnc38dcd392016-02-09 23:19:4913518 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0913519 std::unique_ptr<SpdySerializedFrame> resp1(
bnc38dcd392016-02-09 23:19:4913520 spdy_util_wrapped.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0913521 std::unique_ptr<SpdySerializedFrame> body1(
bnc38dcd392016-02-09 23:19:4913522 spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913523 std::unique_ptr<SpdySerializedFrame> wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3813524 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
danakj1fd259a02016-04-16 03:17:0913525 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3813526 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
danakj1fd259a02016-04-16 03:17:0913527 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5513528 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913529 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5513530 spdy_util_.ConstructSpdyBodyFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3313531 MockRead reads1[] = {
13532 CreateMockRead(*conn_resp, 1),
13533 MockRead(ASYNC, ERR_IO_PENDING, 3),
13534 CreateMockRead(*wrapped_resp1, 4),
13535 CreateMockRead(*wrapped_body1, 5),
13536 MockRead(ASYNC, ERR_IO_PENDING, 7),
13537 CreateMockRead(*resp2, 8),
13538 CreateMockRead(*body2, 9),
13539 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
13540 };
[email protected]8450d722012-07-02 19:14:0413541
mmenke666a6fea2015-12-19 04:16:3313542 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13543 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413544 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713545 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413546
rdsmith82957ad2015-09-16 19:42:0313547 session_deps_.proxy_service =
13548 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5113549 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713550 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0413551 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3813552 ssl1.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313553 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0413554 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3813555 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313556 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13557 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0413558
danakj1fd259a02016-04-16 03:17:0913559 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0413560
13561 // Start the first transaction to set up the SpdySession
13562 HttpRequestInfo request1;
13563 request1.method = "GET";
13564 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413565 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013566 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413567 TestCompletionCallback callback1;
mmenke666a6fea2015-12-19 04:16:3313568 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0413569
mmenke666a6fea2015-12-19 04:16:3313570 // This pause is a hack to avoid running into https://crbug.com/497228.
13571 data1.RunUntilPaused();
13572 base::RunLoop().RunUntilIdle();
13573 data1.Resume();
13574 EXPECT_EQ(OK, callback1.GetResult(rv));
[email protected]8450d722012-07-02 19:14:0413575 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13576
[email protected]f6c63db52013-02-02 00:35:2213577 LoadTimingInfo load_timing_info1;
13578 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
13579 TestLoadTimingNotReusedWithPac(load_timing_info1,
13580 CONNECT_TIMING_HAS_SSL_TIMES);
13581
mmenke666a6fea2015-12-19 04:16:3313582 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0413583 HttpRequestInfo request2;
13584 request2.method = "GET";
13585 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413586 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013587 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413588 TestCompletionCallback callback2;
mmenke666a6fea2015-12-19 04:16:3313589 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0413590
mmenke666a6fea2015-12-19 04:16:3313591 // This pause is a hack to avoid running into https://crbug.com/497228.
13592 data1.RunUntilPaused();
13593 base::RunLoop().RunUntilIdle();
13594 data1.Resume();
13595 EXPECT_EQ(OK, callback2.GetResult(rv));
13596
[email protected]8450d722012-07-02 19:14:0413597 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2213598
13599 LoadTimingInfo load_timing_info2;
13600 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
13601 // The established SPDY sessions is considered reused by the HTTP request.
13602 TestLoadTimingReusedWithPac(load_timing_info2);
13603 // HTTP requests over a SPDY session should have a different connection
13604 // socket_log_id than requests over a tunnel.
13605 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0413606}
13607
[email protected]2d88e7d2012-07-19 17:55:1713608// Test that in the case where we have a SPDY session to a SPDY proxy
13609// that we do not pool other origins that resolve to the same IP when
13610// the certificate does not match the new origin.
13611// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0213612TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2313613 const std::string url1 = "http://www.example.org/";
13614 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1713615 const std::string ip_addr = "1.2.3.4";
13616
rdsmithebb50aa2015-11-12 03:44:3813617 // Second SpdyTestUtil instance for the second socket.
13618 SpdyTestUtil spdy_util_secure(GetProtocol(), GetDependenciesFromPriority());
13619
[email protected]2d88e7d2012-07-19 17:55:1713620 // SPDY GET for HTTP URL (through SPDY proxy)
danakj1fd259a02016-04-16 03:17:0913621 std::unique_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2313622 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
danakj1fd259a02016-04-16 03:17:0913623 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913624 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1713625
13626 MockWrite writes1[] = {
13627 CreateMockWrite(*req1, 0),
13628 };
13629
danakj1fd259a02016-04-16 03:17:0913630 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5513631 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913632 std::unique_ptr<SpdySerializedFrame> body1(
bncb03b1092016-04-06 11:19:5513633 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1713634 MockRead reads1[] = {
mmenke666a6fea2015-12-19 04:16:3313635 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*resp1, 2),
13636 CreateMockRead(*body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1713637 };
13638
mmenke666a6fea2015-12-19 04:16:3313639 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13640 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3213641 IPAddress ip;
martijn654c8c42016-02-10 22:10:5913642 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1713643 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13644 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3313645 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1713646
13647 // SPDY GET for HTTPS URL (direct)
danakj1fd259a02016-04-16 03:17:0913648 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913649 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1713650
13651 MockWrite writes2[] = {
13652 CreateMockWrite(*req2, 0),
13653 };
13654
danakj1fd259a02016-04-16 03:17:0913655 std::unique_ptr<SpdySerializedFrame> resp2(
rdsmithebb50aa2015-11-12 03:44:3813656 spdy_util_secure.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913657 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5513658 spdy_util_secure.ConstructSpdyBodyFrame(1, true));
mmenke666a6fea2015-12-19 04:16:3313659 MockRead reads2[] = {CreateMockRead(*resp2, 1), CreateMockRead(*body2, 2),
13660 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1713661
mmenke666a6fea2015-12-19 04:16:3313662 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13663 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1713664 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3313665 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1713666
13667 // Set up a proxy config that sends HTTP requests to a proxy, and
13668 // all others direct.
13669 ProxyConfig proxy_config;
13670 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0713671 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0913672 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0413673 NULL));
[email protected]2d88e7d2012-07-19 17:55:1713674
bncce36dca22015-04-21 22:11:2313675 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3813676 ssl1.SetNextProto(GetProtocol());
[email protected]2d88e7d2012-07-19 17:55:1713677 // Load a valid cert. Note, that this does not need to
13678 // be valid for proxy because the MockSSLClientSocket does
13679 // not actually verify it. But SpdySession will use this
13680 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2313681 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5213682 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3313683 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13684 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1713685
13686 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3813687 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313688 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13689 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1713690
[email protected]bb88e1d32013-05-03 23:11:0713691 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2313692 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0713693 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1713694
danakj1fd259a02016-04-16 03:17:0913695 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1713696
13697 // Start the first transaction to set up the SpdySession
13698 HttpRequestInfo request1;
13699 request1.method = "GET";
13700 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1713701 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013702 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713703 TestCompletionCallback callback1;
13704 ASSERT_EQ(ERR_IO_PENDING,
13705 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
mmenke666a6fea2015-12-19 04:16:3313706 // This pause is a hack to avoid running into https://crbug.com/497228.
13707 data1.RunUntilPaused();
13708 base::RunLoop().RunUntilIdle();
13709 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1713710
[email protected]2d88e7d2012-07-19 17:55:1713711 EXPECT_EQ(OK, callback1.WaitForResult());
13712 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13713
13714 // Now, start the HTTP request
13715 HttpRequestInfo request2;
13716 request2.method = "GET";
13717 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1713718 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013719 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713720 TestCompletionCallback callback2;
13721 EXPECT_EQ(ERR_IO_PENDING,
13722 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413723 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1713724
13725 ASSERT_TRUE(callback2.have_result());
13726 EXPECT_EQ(OK, callback2.WaitForResult());
13727 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13728}
13729
[email protected]85f97342013-04-17 06:12:2413730// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
13731// error) in SPDY session, removes the socket from pool and closes the SPDY
13732// session. Verify that new url's from the same HttpNetworkSession (and a new
13733// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0213734TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2313735 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2413736
13737 MockRead reads1[] = {
13738 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
13739 };
13740
mmenke11eb5152015-06-09 14:50:5013741 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2413742
danakj1fd259a02016-04-16 03:17:0913743 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913744 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2413745 MockWrite writes2[] = {
13746 CreateMockWrite(*req2, 0),
13747 };
13748
danakj1fd259a02016-04-16 03:17:0913749 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5513750 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913751 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5513752 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2413753 MockRead reads2[] = {
13754 CreateMockRead(*resp2, 1),
13755 CreateMockRead(*body2, 2),
13756 MockRead(ASYNC, OK, 3) // EOF
13757 };
13758
mmenke11eb5152015-06-09 14:50:5013759 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13760 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2413761
[email protected]85f97342013-04-17 06:12:2413762 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813763 ssl1.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5013764 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13765 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2413766
13767 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813768 ssl2.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5013769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13770 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2413771
danakj1fd259a02016-04-16 03:17:0913772 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5013773 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2413774
13775 // Start the first transaction to set up the SpdySession and verify that
13776 // connection was closed.
13777 HttpRequestInfo request1;
13778 request1.method = "GET";
13779 request1.url = GURL(https_url);
13780 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013781 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413782 TestCompletionCallback callback1;
13783 EXPECT_EQ(ERR_IO_PENDING,
13784 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413785 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
13786
13787 // Now, start the second request and make sure it succeeds.
13788 HttpRequestInfo request2;
13789 request2.method = "GET";
13790 request2.url = GURL(https_url);
13791 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013792 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413793 TestCompletionCallback callback2;
13794 EXPECT_EQ(ERR_IO_PENDING,
13795 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413796
mmenke11eb5152015-06-09 14:50:5013797 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2413798 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13799}
13800
[email protected]23e482282013-06-14 16:08:0213801TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0313802 ClientSocketPoolManager::set_max_sockets_per_group(
13803 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13804 ClientSocketPoolManager::set_max_sockets_per_pool(
13805 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13806
13807 // Use two different hosts with different IPs so they don't get pooled.
13808 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
13809 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0913810 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0313811
13812 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813813 ssl1.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0313814 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813815 ssl2.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0313816 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13817 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13818
danakj1fd259a02016-04-16 03:17:0913819 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913820 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0313821 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1313822 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0313823 };
danakj1fd259a02016-04-16 03:17:0913824 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213825 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913826 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213827 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313828 MockRead spdy1_reads[] = {
mmenkee24011922015-12-17 22:12:5913829 CreateMockRead(*host1_resp, 1), CreateMockRead(*host1_resp_body, 2),
13830 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313831 };
13832
rdsmithebb50aa2015-11-12 03:44:3813833 // Use a separate test instance for the separate SpdySession that will be
13834 // created.
13835 SpdyTestUtil spdy_util_2(GetProtocol(), GetDependenciesFromPriority());
danakj1fd259a02016-04-16 03:17:0913836 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1313837 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
13838 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0313839 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
13840
danakj1fd259a02016-04-16 03:17:0913841 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913842 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0313843 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1313844 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0313845 };
danakj1fd259a02016-04-16 03:17:0913846 std::unique_ptr<SpdySerializedFrame> host2_resp(
rdsmithebb50aa2015-11-12 03:44:3813847 spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913848 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
rdsmithebb50aa2015-11-12 03:44:3813849 spdy_util_2.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313850 MockRead spdy2_reads[] = {
mmenkee24011922015-12-17 22:12:5913851 CreateMockRead(*host2_resp, 1), CreateMockRead(*host2_resp_body, 2),
13852 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313853 };
13854
danakj1fd259a02016-04-16 03:17:0913855 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1313856 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
13857 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0313858 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
13859
13860 MockWrite http_write[] = {
13861 MockWrite("GET / HTTP/1.1\r\n"
13862 "Host: www.a.com\r\n"
13863 "Connection: keep-alive\r\n\r\n"),
13864 };
13865
13866 MockRead http_read[] = {
13867 MockRead("HTTP/1.1 200 OK\r\n"),
13868 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13869 MockRead("Content-Length: 6\r\n\r\n"),
13870 MockRead("hello!"),
13871 };
13872 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
13873 http_write, arraysize(http_write));
13874 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13875
13876 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4013877 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5313878 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313879 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613880 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313881
13882 TestCompletionCallback callback;
13883 HttpRequestInfo request1;
13884 request1.method = "GET";
13885 request1.url = GURL("https://www.a.com/");
13886 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0913887 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013888 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313889
13890 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
13891 EXPECT_EQ(ERR_IO_PENDING, rv);
13892 EXPECT_EQ(OK, callback.WaitForResult());
13893
13894 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213895 ASSERT_TRUE(response);
13896 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213897 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0313898 EXPECT_TRUE(response->was_fetched_via_spdy);
13899 EXPECT_TRUE(response->was_npn_negotiated);
13900
13901 std::string response_data;
13902 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13903 EXPECT_EQ("hello!", response_data);
13904 trans.reset();
13905 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613906 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313907
13908 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4013909 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5313910 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313911 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613912 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313913 HttpRequestInfo request2;
13914 request2.method = "GET";
13915 request2.url = GURL("https://www.b.com/");
13916 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013917 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313918
13919 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
13920 EXPECT_EQ(ERR_IO_PENDING, rv);
13921 EXPECT_EQ(OK, callback.WaitForResult());
13922
13923 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213924 ASSERT_TRUE(response);
13925 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213926 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0313927 EXPECT_TRUE(response->was_fetched_via_spdy);
13928 EXPECT_TRUE(response->was_npn_negotiated);
13929 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13930 EXPECT_EQ("hello!", response_data);
13931 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613932 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313933 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613934 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313935
13936 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4013937 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5313938 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313939 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613940 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0313941 HttpRequestInfo request3;
13942 request3.method = "GET";
13943 request3.url = GURL("http://www.a.com/");
13944 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013945 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313946
13947 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
13948 EXPECT_EQ(ERR_IO_PENDING, rv);
13949 EXPECT_EQ(OK, callback.WaitForResult());
13950
13951 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213952 ASSERT_TRUE(response);
13953 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0313954 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13955 EXPECT_FALSE(response->was_fetched_via_spdy);
13956 EXPECT_FALSE(response->was_npn_negotiated);
13957 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13958 EXPECT_EQ("hello!", response_data);
13959 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613960 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313961 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613962 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313963}
13964
[email protected]79e1fd62013-06-20 06:50:0413965TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
13966 HttpRequestInfo request;
13967 request.method = "GET";
bncce36dca22015-04-21 22:11:2313968 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413969 request.load_flags = 0;
13970
danakj1fd259a02016-04-16 03:17:0913971 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13972 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113973 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413974
ttuttled9dbc652015-09-29 20:00:5913975 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413976 StaticSocketDataProvider data;
13977 data.set_connect_data(mock_connect);
13978 session_deps_.socket_factory->AddSocketDataProvider(&data);
13979
13980 TestCompletionCallback callback;
13981
13982 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13983 EXPECT_EQ(ERR_IO_PENDING, rv);
13984
13985 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913986 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413987
[email protected]79e1fd62013-06-20 06:50:0413988 // We don't care whether this succeeds or fails, but it shouldn't crash.
13989 HttpRequestHeaders request_headers;
13990 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713991
13992 ConnectionAttempts attempts;
13993 trans->GetConnectionAttempts(&attempts);
13994 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913995 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13996
13997 IPEndPoint endpoint;
13998 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13999 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414000}
14001
14002TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
14003 HttpRequestInfo request;
14004 request.method = "GET";
bncce36dca22015-04-21 22:11:2314005 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414006 request.load_flags = 0;
14007
danakj1fd259a02016-04-16 03:17:0914008 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14009 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114010 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414011
ttuttled9dbc652015-09-29 20:00:5914012 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414013 StaticSocketDataProvider data;
14014 data.set_connect_data(mock_connect);
14015 session_deps_.socket_factory->AddSocketDataProvider(&data);
14016
14017 TestCompletionCallback callback;
14018
14019 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14020 EXPECT_EQ(ERR_IO_PENDING, rv);
14021
14022 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5914023 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0414024
[email protected]79e1fd62013-06-20 06:50:0414025 // We don't care whether this succeeds or fails, but it shouldn't crash.
14026 HttpRequestHeaders request_headers;
14027 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714028
14029 ConnectionAttempts attempts;
14030 trans->GetConnectionAttempts(&attempts);
14031 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5914032 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
14033
14034 IPEndPoint endpoint;
14035 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
14036 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414037}
14038
14039TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
14040 HttpRequestInfo request;
14041 request.method = "GET";
bncce36dca22015-04-21 22:11:2314042 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414043 request.load_flags = 0;
14044
danakj1fd259a02016-04-16 03:17:0914045 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14046 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114047 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414048
14049 MockWrite data_writes[] = {
14050 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14051 };
14052 MockRead data_reads[] = {
14053 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14054 };
14055
14056 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14057 data_writes, arraysize(data_writes));
14058 session_deps_.socket_factory->AddSocketDataProvider(&data);
14059
14060 TestCompletionCallback callback;
14061
14062 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14063 EXPECT_EQ(ERR_IO_PENDING, rv);
14064
14065 rv = callback.WaitForResult();
14066 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14067
[email protected]79e1fd62013-06-20 06:50:0414068 HttpRequestHeaders request_headers;
14069 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14070 EXPECT_TRUE(request_headers.HasHeader("Host"));
14071}
14072
14073TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
14074 HttpRequestInfo request;
14075 request.method = "GET";
bncce36dca22015-04-21 22:11:2314076 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414077 request.load_flags = 0;
14078
danakj1fd259a02016-04-16 03:17:0914079 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14080 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114081 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414082
14083 MockWrite data_writes[] = {
14084 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14085 };
14086 MockRead data_reads[] = {
14087 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14088 };
14089
14090 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14091 data_writes, arraysize(data_writes));
14092 session_deps_.socket_factory->AddSocketDataProvider(&data);
14093
14094 TestCompletionCallback callback;
14095
14096 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14097 EXPECT_EQ(ERR_IO_PENDING, rv);
14098
14099 rv = callback.WaitForResult();
14100 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14101
[email protected]79e1fd62013-06-20 06:50:0414102 HttpRequestHeaders request_headers;
14103 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14104 EXPECT_TRUE(request_headers.HasHeader("Host"));
14105}
14106
14107TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
14108 HttpRequestInfo request;
14109 request.method = "GET";
bncce36dca22015-04-21 22:11:2314110 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414111 request.load_flags = 0;
14112
danakj1fd259a02016-04-16 03:17:0914113 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14114 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114115 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414116
14117 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314118 MockWrite(
14119 "GET / HTTP/1.1\r\n"
14120 "Host: www.example.org\r\n"
14121 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414122 };
14123 MockRead data_reads[] = {
14124 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14125 };
14126
14127 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14128 data_writes, arraysize(data_writes));
14129 session_deps_.socket_factory->AddSocketDataProvider(&data);
14130
14131 TestCompletionCallback callback;
14132
14133 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14134 EXPECT_EQ(ERR_IO_PENDING, rv);
14135
14136 rv = callback.WaitForResult();
14137 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14138
[email protected]79e1fd62013-06-20 06:50:0414139 HttpRequestHeaders request_headers;
14140 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14141 EXPECT_TRUE(request_headers.HasHeader("Host"));
14142}
14143
14144TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
14145 HttpRequestInfo request;
14146 request.method = "GET";
bncce36dca22015-04-21 22:11:2314147 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414148 request.load_flags = 0;
14149
danakj1fd259a02016-04-16 03:17:0914150 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14151 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114152 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414153
14154 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314155 MockWrite(
14156 "GET / HTTP/1.1\r\n"
14157 "Host: www.example.org\r\n"
14158 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414159 };
14160 MockRead data_reads[] = {
14161 MockRead(ASYNC, ERR_CONNECTION_RESET),
14162 };
14163
14164 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14165 data_writes, arraysize(data_writes));
14166 session_deps_.socket_factory->AddSocketDataProvider(&data);
14167
14168 TestCompletionCallback callback;
14169
14170 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14171 EXPECT_EQ(ERR_IO_PENDING, rv);
14172
14173 rv = callback.WaitForResult();
14174 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14175
[email protected]79e1fd62013-06-20 06:50:0414176 HttpRequestHeaders request_headers;
14177 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14178 EXPECT_TRUE(request_headers.HasHeader("Host"));
14179}
14180
14181TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
14182 HttpRequestInfo request;
14183 request.method = "GET";
bncce36dca22015-04-21 22:11:2314184 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414185 request.load_flags = 0;
14186 request.extra_headers.SetHeader("X-Foo", "bar");
14187
danakj1fd259a02016-04-16 03:17:0914188 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14189 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114190 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414191
14192 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314193 MockWrite(
14194 "GET / HTTP/1.1\r\n"
14195 "Host: www.example.org\r\n"
14196 "Connection: keep-alive\r\n"
14197 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414198 };
14199 MockRead data_reads[] = {
14200 MockRead("HTTP/1.1 200 OK\r\n"
14201 "Content-Length: 5\r\n\r\n"
14202 "hello"),
14203 MockRead(ASYNC, ERR_UNEXPECTED),
14204 };
14205
14206 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14207 data_writes, arraysize(data_writes));
14208 session_deps_.socket_factory->AddSocketDataProvider(&data);
14209
14210 TestCompletionCallback callback;
14211
14212 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14213 EXPECT_EQ(ERR_IO_PENDING, rv);
14214
14215 rv = callback.WaitForResult();
14216 EXPECT_EQ(OK, rv);
14217
14218 HttpRequestHeaders request_headers;
14219 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14220 std::string foo;
14221 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14222 EXPECT_EQ("bar", foo);
14223}
14224
[email protected]bf828982013-08-14 18:01:4714225namespace {
14226
yhiranoa7e05bb2014-11-06 05:40:3914227// Fake HttpStream that simply records calls to SetPriority().
14228class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314229 public base::SupportsWeakPtr<FakeStream> {
14230 public:
14231 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014232 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314233
14234 RequestPriority priority() const { return priority_; }
14235
dchengb03027d2014-10-21 12:00:2014236 int InitializeStream(const HttpRequestInfo* request_info,
14237 RequestPriority priority,
14238 const BoundNetLog& net_log,
14239 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314240 return ERR_IO_PENDING;
14241 }
14242
dchengb03027d2014-10-21 12:00:2014243 int SendRequest(const HttpRequestHeaders& request_headers,
14244 HttpResponseInfo* response,
14245 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314246 ADD_FAILURE();
14247 return ERR_UNEXPECTED;
14248 }
14249
dchengb03027d2014-10-21 12:00:2014250 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314251 ADD_FAILURE();
14252 return ERR_UNEXPECTED;
14253 }
14254
dchengb03027d2014-10-21 12:00:2014255 int ReadResponseBody(IOBuffer* buf,
14256 int buf_len,
14257 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314258 ADD_FAILURE();
14259 return ERR_UNEXPECTED;
14260 }
14261
dchengb03027d2014-10-21 12:00:2014262 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314263
dchengb03027d2014-10-21 12:00:2014264 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314265 ADD_FAILURE();
14266 return false;
14267 }
14268
dchengb03027d2014-10-21 12:00:2014269 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314270 ADD_FAILURE();
14271 return false;
14272 }
14273
dchengb03027d2014-10-21 12:00:2014274 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314275
mmenkebd84c392015-09-02 14:12:3414276 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314277
sclittle4de1bab92015-09-22 21:28:2414278 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914279 ADD_FAILURE();
14280 return 0;
14281 }
14282
sclittlebe1ccf62015-09-02 19:40:3614283 int64_t GetTotalSentBytes() const override {
14284 ADD_FAILURE();
14285 return 0;
14286 }
14287
dchengb03027d2014-10-21 12:00:2014288 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314289 ADD_FAILURE();
14290 return false;
14291 }
14292
dchengb03027d2014-10-21 12:00:2014293 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14294
14295 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314296 ADD_FAILURE();
14297 }
14298
ttuttled9dbc652015-09-29 20:00:5914299 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14300
nharperb7441ef2016-01-25 23:54:1414301 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14302 std::vector<uint8_t>* out) override {
14303 ADD_FAILURE();
14304 return ERR_NOT_IMPLEMENTED;
14305 }
14306
dchengb03027d2014-10-21 12:00:2014307 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314308
zhongyica364fbb2015-12-12 03:39:1214309 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14310
dchengb03027d2014-10-21 12:00:2014311 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314312
yhiranoa7e05bb2014-11-06 05:40:3914313 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
14314
14315 HttpStream* RenewStreamForAuth() override { return NULL; }
14316
[email protected]e86839fd2013-08-14 18:29:0314317 private:
14318 RequestPriority priority_;
14319
14320 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14321};
14322
14323// Fake HttpStreamRequest that simply records calls to SetPriority()
14324// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714325class FakeStreamRequest : public HttpStreamRequest,
14326 public base::SupportsWeakPtr<FakeStreamRequest> {
14327 public:
[email protected]e86839fd2013-08-14 18:29:0314328 FakeStreamRequest(RequestPriority priority,
14329 HttpStreamRequest::Delegate* delegate)
14330 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414331 delegate_(delegate),
14332 websocket_stream_create_helper_(NULL) {}
14333
14334 FakeStreamRequest(RequestPriority priority,
14335 HttpStreamRequest::Delegate* delegate,
14336 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14337 : priority_(priority),
14338 delegate_(delegate),
14339 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314340
dchengb03027d2014-10-21 12:00:2014341 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714342
14343 RequestPriority priority() const { return priority_; }
14344
[email protected]831e4a32013-11-14 02:14:4414345 const WebSocketHandshakeStreamBase::CreateHelper*
14346 websocket_stream_create_helper() const {
14347 return websocket_stream_create_helper_;
14348 }
14349
[email protected]e86839fd2013-08-14 18:29:0314350 // Create a new FakeStream and pass it to the request's
14351 // delegate. Returns a weak pointer to the FakeStream.
14352 base::WeakPtr<FakeStream> FinishStreamRequest() {
14353 FakeStream* fake_stream = new FakeStream(priority_);
14354 // Do this before calling OnStreamReady() as OnStreamReady() may
14355 // immediately delete |fake_stream|.
14356 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14357 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14358 return weak_stream;
14359 }
14360
dchengb03027d2014-10-21 12:00:2014361 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714362 ADD_FAILURE();
14363 return ERR_UNEXPECTED;
14364 }
14365
dchengb03027d2014-10-21 12:00:2014366 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714367 ADD_FAILURE();
14368 return LoadState();
14369 }
14370
dchengb03027d2014-10-21 12:00:2014371 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714372
dchengb03027d2014-10-21 12:00:2014373 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714374
dchengb03027d2014-10-21 12:00:2014375 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714376
dchengb03027d2014-10-21 12:00:2014377 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714378
ttuttle1f2d7e92015-04-28 16:17:4714379 const ConnectionAttempts& connection_attempts() const override {
14380 static ConnectionAttempts no_attempts;
14381 return no_attempts;
14382 }
14383
[email protected]bf828982013-08-14 18:01:4714384 private:
14385 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314386 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414387 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714388
14389 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14390};
14391
14392// Fake HttpStreamFactory that vends FakeStreamRequests.
14393class FakeStreamFactory : public HttpStreamFactory {
14394 public:
14395 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014396 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714397
14398 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14399 // RequestStream() (which may be NULL if it was destroyed already).
14400 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14401 return last_stream_request_;
14402 }
14403
dchengb03027d2014-10-21 12:00:2014404 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14405 RequestPriority priority,
14406 const SSLConfig& server_ssl_config,
14407 const SSLConfig& proxy_ssl_config,
14408 HttpStreamRequest::Delegate* delegate,
14409 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314410 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714411 last_stream_request_ = fake_request->AsWeakPtr();
14412 return fake_request;
14413 }
14414
xunjieli5749218c2016-03-22 16:43:0614415 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0814416 const HttpRequestInfo& info,
14417 RequestPriority priority,
14418 const SSLConfig& server_ssl_config,
14419 const SSLConfig& proxy_ssl_config,
14420 HttpStreamRequest::Delegate* delegate,
14421 const BoundNetLog& net_log) override {
14422 NOTREACHED();
14423 return nullptr;
14424 }
14425
dchengb03027d2014-10-21 12:00:2014426 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714427 const HttpRequestInfo& info,
14428 RequestPriority priority,
14429 const SSLConfig& server_ssl_config,
14430 const SSLConfig& proxy_ssl_config,
14431 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614432 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1314433 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414434 FakeStreamRequest* fake_request =
14435 new FakeStreamRequest(priority, delegate, create_helper);
14436 last_stream_request_ = fake_request->AsWeakPtr();
14437 return fake_request;
[email protected]bf828982013-08-14 18:01:4714438 }
14439
dchengb03027d2014-10-21 12:00:2014440 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5914441 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4714442 ADD_FAILURE();
14443 }
14444
dchengb03027d2014-10-21 12:00:2014445 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714446 ADD_FAILURE();
14447 return NULL;
14448 }
14449
14450 private:
14451 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14452
14453 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14454};
14455
Adam Rice425cf122015-01-19 06:18:2414456// TODO(ricea): Maybe unify this with the one in
14457// url_request_http_job_unittest.cc ?
14458class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14459 public:
danakj1fd259a02016-04-16 03:17:0914460 FakeWebSocketBasicHandshakeStream(
14461 std::unique_ptr<ClientSocketHandle> connection,
14462 bool using_proxy)
Adam Rice425cf122015-01-19 06:18:2414463 : state_(connection.release(), using_proxy) {}
14464
14465 // Fake implementation of HttpStreamBase methods.
14466 // This ends up being quite "real" because this object has to really send data
14467 // on the mock socket. It might be easier to use the real implementation, but
14468 // the fact that the WebSocket code is not compiled on iOS makes that
14469 // difficult.
14470 int InitializeStream(const HttpRequestInfo* request_info,
14471 RequestPriority priority,
14472 const BoundNetLog& net_log,
14473 const CompletionCallback& callback) override {
14474 state_.Initialize(request_info, priority, net_log, callback);
14475 return OK;
14476 }
14477
14478 int SendRequest(const HttpRequestHeaders& request_headers,
14479 HttpResponseInfo* response,
14480 const CompletionCallback& callback) override {
14481 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
14482 response, callback);
14483 }
14484
14485 int ReadResponseHeaders(const CompletionCallback& callback) override {
14486 return parser()->ReadResponseHeaders(callback);
14487 }
14488
14489 int ReadResponseBody(IOBuffer* buf,
14490 int buf_len,
14491 const CompletionCallback& callback) override {
14492 NOTREACHED();
14493 return ERR_IO_PENDING;
14494 }
14495
14496 void Close(bool not_reusable) override {
14497 if (parser())
14498 parser()->Close(true);
14499 }
14500
14501 bool IsResponseBodyComplete() const override {
14502 NOTREACHED();
14503 return false;
14504 }
14505
Adam Rice425cf122015-01-19 06:18:2414506 bool IsConnectionReused() const override {
14507 NOTREACHED();
14508 return false;
14509 }
14510 void SetConnectionReused() override { NOTREACHED(); }
14511
mmenkebd84c392015-09-02 14:12:3414512 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2414513
sclittle4de1bab92015-09-22 21:28:2414514 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2414515 NOTREACHED();
14516 return 0;
14517 }
14518
sclittlebe1ccf62015-09-02 19:40:3614519 int64_t GetTotalSentBytes() const override {
14520 NOTREACHED();
14521 return 0;
14522 }
14523
Adam Rice425cf122015-01-19 06:18:2414524 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
14525 NOTREACHED();
14526 return false;
14527 }
14528
Adam Ricecb76ac62015-02-20 05:33:2514529 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2414530
14531 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
14532 NOTREACHED();
14533 }
14534
ttuttled9dbc652015-09-29 20:00:5914535 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14536
nharperb7441ef2016-01-25 23:54:1414537 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14538 std::vector<uint8_t>* out) override {
14539 ADD_FAILURE();
14540 return ERR_NOT_IMPLEMENTED;
14541 }
14542
Adam Rice425cf122015-01-19 06:18:2414543 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
14544
zhongyica364fbb2015-12-12 03:39:1214545 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14546
Adam Rice425cf122015-01-19 06:18:2414547 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
14548
14549 UploadProgress GetUploadProgress() const override {
14550 NOTREACHED();
14551 return UploadProgress();
14552 }
14553
14554 HttpStream* RenewStreamForAuth() override {
14555 NOTREACHED();
14556 return nullptr;
14557 }
14558
14559 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0914560 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2414561 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0914562 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2414563 }
14564
14565 private:
14566 HttpStreamParser* parser() const { return state_.parser(); }
14567 HttpBasicState state_;
14568
14569 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
14570};
14571
[email protected]831e4a32013-11-14 02:14:4414572// TODO(yhirano): Split this class out into a net/websockets file, if it is
14573// worth doing.
14574class FakeWebSocketStreamCreateHelper :
14575 public WebSocketHandshakeStreamBase::CreateHelper {
14576 public:
dchengb03027d2014-10-21 12:00:2014577 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0914578 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1314579 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4814580 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2414581 using_proxy);
[email protected]831e4a32013-11-14 02:14:4414582 }
14583
dchengb03027d2014-10-21 12:00:2014584 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4414585 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1314586 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4414587 NOTREACHED();
14588 return NULL;
14589 };
14590
dchengb03027d2014-10-21 12:00:2014591 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4414592
danakj1fd259a02016-04-16 03:17:0914593 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4414594 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0914595 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4414596 }
14597};
14598
[email protected]bf828982013-08-14 18:01:4714599} // namespace
14600
14601// Make sure that HttpNetworkTransaction passes on its priority to its
14602// stream request on start.
14603TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0914604 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214605 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714606 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0914607 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714608
dcheng48459ac22014-08-26 00:46:4114609 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714610
wezca1070932016-05-26 20:30:5214611 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4714612
14613 HttpRequestInfo request;
14614 TestCompletionCallback callback;
14615 EXPECT_EQ(ERR_IO_PENDING,
14616 trans.Start(&request, callback.callback(), BoundNetLog()));
14617
14618 base::WeakPtr<FakeStreamRequest> fake_request =
14619 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214620 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4714621 EXPECT_EQ(LOW, fake_request->priority());
14622}
14623
14624// Make sure that HttpNetworkTransaction passes on its priority
14625// updates to its stream request.
14626TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0914627 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214628 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714629 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0914630 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714631
dcheng48459ac22014-08-26 00:46:4114632 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714633
14634 HttpRequestInfo request;
14635 TestCompletionCallback callback;
14636 EXPECT_EQ(ERR_IO_PENDING,
14637 trans.Start(&request, callback.callback(), BoundNetLog()));
14638
14639 base::WeakPtr<FakeStreamRequest> fake_request =
14640 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214641 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4714642 EXPECT_EQ(LOW, fake_request->priority());
14643
14644 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5214645 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4714646 EXPECT_EQ(LOWEST, fake_request->priority());
14647}
14648
[email protected]e86839fd2013-08-14 18:29:0314649// Make sure that HttpNetworkTransaction passes on its priority
14650// updates to its stream.
14651TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0914652 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214653 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0314654 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0914655 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0314656
dcheng48459ac22014-08-26 00:46:4114657 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0314658
14659 HttpRequestInfo request;
14660 TestCompletionCallback callback;
14661 EXPECT_EQ(ERR_IO_PENDING,
14662 trans.Start(&request, callback.callback(), BoundNetLog()));
14663
14664 base::WeakPtr<FakeStreamRequest> fake_request =
14665 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214666 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0314667 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5214668 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0314669 EXPECT_EQ(LOW, fake_stream->priority());
14670
14671 trans.SetPriority(LOWEST);
14672 EXPECT_EQ(LOWEST, fake_stream->priority());
14673}
14674
[email protected]831e4a32013-11-14 02:14:4414675TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
14676 // The same logic needs to be tested for both ws: and wss: schemes, but this
14677 // test is already parameterised on NextProto, so it uses a loop to verify
14678 // that the different schemes work.
bncce36dca22015-04-21 22:11:2314679 std::string test_cases[] = {"ws://www.example.org/",
14680 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4414681 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0914682 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214683 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4414684 FakeStreamFactory* fake_factory = new FakeStreamFactory();
14685 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2314686 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0914687 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4414688
dcheng48459ac22014-08-26 00:46:4114689 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4414690 trans.SetWebSocketHandshakeStreamCreateHelper(
14691 &websocket_stream_create_helper);
14692
14693 HttpRequestInfo request;
14694 TestCompletionCallback callback;
14695 request.method = "GET";
14696 request.url = GURL(test_cases[i]);
14697
14698 EXPECT_EQ(ERR_IO_PENDING,
14699 trans.Start(&request, callback.callback(), BoundNetLog()));
14700
14701 base::WeakPtr<FakeStreamRequest> fake_request =
14702 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214703 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4414704 EXPECT_EQ(&websocket_stream_create_helper,
14705 fake_request->websocket_stream_create_helper());
14706 }
14707}
14708
[email protected]043b68c82013-08-22 23:41:5214709// Tests that when a used socket is returned to the SSL socket pool, it's closed
14710// if the transport socket pool is stalled on the global socket limit.
14711TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
14712 ClientSocketPoolManager::set_max_sockets_per_group(
14713 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14714 ClientSocketPoolManager::set_max_sockets_per_pool(
14715 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14716
14717 // Set up SSL request.
14718
14719 HttpRequestInfo ssl_request;
14720 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2314721 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214722
14723 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2314724 MockWrite(
14725 "GET / HTTP/1.1\r\n"
14726 "Host: www.example.org\r\n"
14727 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214728 };
14729 MockRead ssl_reads[] = {
14730 MockRead("HTTP/1.1 200 OK\r\n"),
14731 MockRead("Content-Length: 11\r\n\r\n"),
14732 MockRead("hello world"),
14733 MockRead(SYNCHRONOUS, OK),
14734 };
14735 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
14736 ssl_writes, arraysize(ssl_writes));
14737 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14738
14739 SSLSocketDataProvider ssl(ASYNC, OK);
14740 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14741
14742 // Set up HTTP request.
14743
14744 HttpRequestInfo http_request;
14745 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314746 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214747
14748 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314749 MockWrite(
14750 "GET / HTTP/1.1\r\n"
14751 "Host: www.example.org\r\n"
14752 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214753 };
14754 MockRead http_reads[] = {
14755 MockRead("HTTP/1.1 200 OK\r\n"),
14756 MockRead("Content-Length: 7\r\n\r\n"),
14757 MockRead("falafel"),
14758 MockRead(SYNCHRONOUS, OK),
14759 };
14760 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14761 http_writes, arraysize(http_writes));
14762 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14763
danakj1fd259a02016-04-16 03:17:0914764 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214765
14766 // Start the SSL request.
14767 TestCompletionCallback ssl_callback;
danakj1fd259a02016-04-16 03:17:0914768 std::unique_ptr<HttpTransaction> ssl_trans(
[email protected]043b68c82013-08-22 23:41:5214769 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14770 ASSERT_EQ(ERR_IO_PENDING,
14771 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
14772 BoundNetLog()));
14773
14774 // Start the HTTP request. Pool should stall.
14775 TestCompletionCallback http_callback;
danakj1fd259a02016-04-16 03:17:0914776 std::unique_ptr<HttpTransaction> http_trans(
[email protected]043b68c82013-08-22 23:41:5214777 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14778 ASSERT_EQ(ERR_IO_PENDING,
14779 http_trans->Start(&http_request, http_callback.callback(),
14780 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4114781 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214782
14783 // Wait for response from SSL request.
14784 ASSERT_EQ(OK, ssl_callback.WaitForResult());
14785 std::string response_data;
14786 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
14787 EXPECT_EQ("hello world", response_data);
14788
14789 // The SSL socket should automatically be closed, so the HTTP request can
14790 // start.
dcheng48459ac22014-08-26 00:46:4114791 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
14792 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214793
14794 // The HTTP request can now complete.
14795 ASSERT_EQ(OK, http_callback.WaitForResult());
14796 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14797 EXPECT_EQ("falafel", response_data);
14798
dcheng48459ac22014-08-26 00:46:4114799 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214800}
14801
14802// Tests that when a SSL connection is established but there's no corresponding
14803// request that needs it, the new socket is closed if the transport socket pool
14804// is stalled on the global socket limit.
14805TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
14806 ClientSocketPoolManager::set_max_sockets_per_group(
14807 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14808 ClientSocketPoolManager::set_max_sockets_per_pool(
14809 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14810
14811 // Set up an ssl request.
14812
14813 HttpRequestInfo ssl_request;
14814 ssl_request.method = "GET";
14815 ssl_request.url = GURL("https://www.foopy.com/");
14816
14817 // No data will be sent on the SSL socket.
14818 StaticSocketDataProvider ssl_data;
14819 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14820
14821 SSLSocketDataProvider ssl(ASYNC, OK);
14822 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14823
14824 // Set up HTTP request.
14825
14826 HttpRequestInfo http_request;
14827 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314828 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214829
14830 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314831 MockWrite(
14832 "GET / HTTP/1.1\r\n"
14833 "Host: www.example.org\r\n"
14834 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214835 };
14836 MockRead http_reads[] = {
14837 MockRead("HTTP/1.1 200 OK\r\n"),
14838 MockRead("Content-Length: 7\r\n\r\n"),
14839 MockRead("falafel"),
14840 MockRead(SYNCHRONOUS, OK),
14841 };
14842 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14843 http_writes, arraysize(http_writes));
14844 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14845
danakj1fd259a02016-04-16 03:17:0914846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214847
14848 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
14849 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2914850 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5914851 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4114852 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214853
14854 // Start the HTTP request. Pool should stall.
14855 TestCompletionCallback http_callback;
danakj1fd259a02016-04-16 03:17:0914856 std::unique_ptr<HttpTransaction> http_trans(
[email protected]043b68c82013-08-22 23:41:5214857 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14858 ASSERT_EQ(ERR_IO_PENDING,
14859 http_trans->Start(&http_request, http_callback.callback(),
14860 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4114861 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214862
14863 // The SSL connection will automatically be closed once the connection is
14864 // established, to let the HTTP request start.
14865 ASSERT_EQ(OK, http_callback.WaitForResult());
14866 std::string response_data;
14867 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14868 EXPECT_EQ("falafel", response_data);
14869
dcheng48459ac22014-08-26 00:46:4114870 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214871}
14872
[email protected]02d74a02014-04-23 18:10:5414873TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0914874 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2214875 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0914876 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2214877 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414878
14879 HttpRequestInfo request;
14880 request.method = "POST";
14881 request.url = GURL("http://www.foo.com/");
14882 request.upload_data_stream = &upload_data_stream;
14883 request.load_flags = 0;
14884
danakj1fd259a02016-04-16 03:17:0914885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14886 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114887 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414888 // Send headers successfully, but get an error while sending the body.
14889 MockWrite data_writes[] = {
14890 MockWrite("POST / HTTP/1.1\r\n"
14891 "Host: www.foo.com\r\n"
14892 "Connection: keep-alive\r\n"
14893 "Content-Length: 3\r\n\r\n"),
14894 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14895 };
14896
14897 MockRead data_reads[] = {
14898 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14899 MockRead("hello world"),
14900 MockRead(SYNCHRONOUS, OK),
14901 };
14902 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14903 arraysize(data_writes));
14904 session_deps_.socket_factory->AddSocketDataProvider(&data);
14905
14906 TestCompletionCallback callback;
14907
14908 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14909 EXPECT_EQ(ERR_IO_PENDING, rv);
14910
14911 rv = callback.WaitForResult();
14912 EXPECT_EQ(OK, rv);
14913
14914 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214915 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5414916
wezca1070932016-05-26 20:30:5214917 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5414918 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14919
14920 std::string response_data;
14921 rv = ReadTransaction(trans.get(), &response_data);
14922 EXPECT_EQ(OK, rv);
14923 EXPECT_EQ("hello world", response_data);
14924}
14925
14926// This test makes sure the retry logic doesn't trigger when reading an error
14927// response from a server that rejected a POST with a CONNECTION_RESET.
14928TEST_P(HttpNetworkTransactionTest,
14929 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0914930 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414931 MockWrite data_writes[] = {
14932 MockWrite("GET / HTTP/1.1\r\n"
14933 "Host: www.foo.com\r\n"
14934 "Connection: keep-alive\r\n\r\n"),
14935 MockWrite("POST / HTTP/1.1\r\n"
14936 "Host: www.foo.com\r\n"
14937 "Connection: keep-alive\r\n"
14938 "Content-Length: 3\r\n\r\n"),
14939 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14940 };
14941
14942 MockRead data_reads[] = {
14943 MockRead("HTTP/1.1 200 Peachy\r\n"
14944 "Content-Length: 14\r\n\r\n"),
14945 MockRead("first response"),
14946 MockRead("HTTP/1.1 400 Not OK\r\n"
14947 "Content-Length: 15\r\n\r\n"),
14948 MockRead("second response"),
14949 MockRead(SYNCHRONOUS, OK),
14950 };
14951 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14952 arraysize(data_writes));
14953 session_deps_.socket_factory->AddSocketDataProvider(&data);
14954
14955 TestCompletionCallback callback;
14956 HttpRequestInfo request1;
14957 request1.method = "GET";
14958 request1.url = GURL("http://www.foo.com/");
14959 request1.load_flags = 0;
14960
danakj1fd259a02016-04-16 03:17:0914961 std::unique_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4114962 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414963 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
14964 EXPECT_EQ(ERR_IO_PENDING, rv);
14965
14966 rv = callback.WaitForResult();
14967 EXPECT_EQ(OK, rv);
14968
14969 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5214970 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5414971
wezca1070932016-05-26 20:30:5214972 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5414973 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
14974
14975 std::string response_data1;
14976 rv = ReadTransaction(trans1.get(), &response_data1);
14977 EXPECT_EQ(OK, rv);
14978 EXPECT_EQ("first response", response_data1);
14979 // Delete the transaction to release the socket back into the socket pool.
14980 trans1.reset();
14981
danakj1fd259a02016-04-16 03:17:0914982 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2214983 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0914984 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2214985 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414986
14987 HttpRequestInfo request2;
14988 request2.method = "POST";
14989 request2.url = GURL("http://www.foo.com/");
14990 request2.upload_data_stream = &upload_data_stream;
14991 request2.load_flags = 0;
14992
danakj1fd259a02016-04-16 03:17:0914993 std::unique_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4114994 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414995 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
14996 EXPECT_EQ(ERR_IO_PENDING, rv);
14997
14998 rv = callback.WaitForResult();
14999 EXPECT_EQ(OK, rv);
15000
15001 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:5215002 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415003
wezca1070932016-05-26 20:30:5215004 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415005 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15006
15007 std::string response_data2;
15008 rv = ReadTransaction(trans2.get(), &response_data2);
15009 EXPECT_EQ(OK, rv);
15010 EXPECT_EQ("second response", response_data2);
15011}
15012
15013TEST_P(HttpNetworkTransactionTest,
15014 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915015 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215016 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915017 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215018 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415019
15020 HttpRequestInfo request;
15021 request.method = "POST";
15022 request.url = GURL("http://www.foo.com/");
15023 request.upload_data_stream = &upload_data_stream;
15024 request.load_flags = 0;
15025
danakj1fd259a02016-04-16 03:17:0915026 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15027 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115028 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415029 // Send headers successfully, but get an error while sending the body.
15030 MockWrite data_writes[] = {
15031 MockWrite("POST / HTTP/1.1\r\n"
15032 "Host: www.foo.com\r\n"
15033 "Connection: keep-alive\r\n"
15034 "Content-Length: 3\r\n\r\n"
15035 "fo"),
15036 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15037 };
15038
15039 MockRead data_reads[] = {
15040 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15041 MockRead("hello world"),
15042 MockRead(SYNCHRONOUS, OK),
15043 };
15044 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15045 arraysize(data_writes));
15046 session_deps_.socket_factory->AddSocketDataProvider(&data);
15047
15048 TestCompletionCallback callback;
15049
15050 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15051 EXPECT_EQ(ERR_IO_PENDING, rv);
15052
15053 rv = callback.WaitForResult();
15054 EXPECT_EQ(OK, rv);
15055
15056 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215057 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415058
wezca1070932016-05-26 20:30:5215059 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415060 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15061
15062 std::string response_data;
15063 rv = ReadTransaction(trans.get(), &response_data);
15064 EXPECT_EQ(OK, rv);
15065 EXPECT_EQ("hello world", response_data);
15066}
15067
15068// This tests the more common case than the previous test, where headers and
15069// body are not merged into a single request.
15070TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715071 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415072
15073 HttpRequestInfo request;
15074 request.method = "POST";
15075 request.url = GURL("http://www.foo.com/");
15076 request.upload_data_stream = &upload_data_stream;
15077 request.load_flags = 0;
15078
danakj1fd259a02016-04-16 03:17:0915079 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15080 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115081 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415082 // Send headers successfully, but get an error while sending the body.
15083 MockWrite data_writes[] = {
15084 MockWrite("POST / HTTP/1.1\r\n"
15085 "Host: www.foo.com\r\n"
15086 "Connection: keep-alive\r\n"
15087 "Transfer-Encoding: chunked\r\n\r\n"),
15088 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15089 };
15090
15091 MockRead data_reads[] = {
15092 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15093 MockRead("hello world"),
15094 MockRead(SYNCHRONOUS, OK),
15095 };
15096 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15097 arraysize(data_writes));
15098 session_deps_.socket_factory->AddSocketDataProvider(&data);
15099
15100 TestCompletionCallback callback;
15101
15102 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15103 EXPECT_EQ(ERR_IO_PENDING, rv);
15104 // Make sure the headers are sent before adding a chunk. This ensures that
15105 // they can't be merged with the body in a single send. Not currently
15106 // necessary since a chunked body is never merged with headers, but this makes
15107 // the test more future proof.
15108 base::RunLoop().RunUntilIdle();
15109
mmenkecbc2b712014-10-09 20:29:0715110 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415111
15112 rv = callback.WaitForResult();
15113 EXPECT_EQ(OK, rv);
15114
15115 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215116 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415117
wezca1070932016-05-26 20:30:5215118 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415119 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15120
15121 std::string response_data;
15122 rv = ReadTransaction(trans.get(), &response_data);
15123 EXPECT_EQ(OK, rv);
15124 EXPECT_EQ("hello world", response_data);
15125}
15126
15127TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915128 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215129 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915130 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215131 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415132
15133 HttpRequestInfo request;
15134 request.method = "POST";
15135 request.url = GURL("http://www.foo.com/");
15136 request.upload_data_stream = &upload_data_stream;
15137 request.load_flags = 0;
15138
danakj1fd259a02016-04-16 03:17:0915139 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15140 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115141 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415142
15143 MockWrite data_writes[] = {
15144 MockWrite("POST / HTTP/1.1\r\n"
15145 "Host: www.foo.com\r\n"
15146 "Connection: keep-alive\r\n"
15147 "Content-Length: 3\r\n\r\n"),
15148 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15149 };
15150
15151 MockRead data_reads[] = {
15152 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15153 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15154 MockRead("hello world"),
15155 MockRead(SYNCHRONOUS, OK),
15156 };
15157 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15158 arraysize(data_writes));
15159 session_deps_.socket_factory->AddSocketDataProvider(&data);
15160
15161 TestCompletionCallback callback;
15162
15163 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15164 EXPECT_EQ(ERR_IO_PENDING, rv);
15165
15166 rv = callback.WaitForResult();
15167 EXPECT_EQ(OK, rv);
15168
15169 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215170 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415171
wezca1070932016-05-26 20:30:5215172 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415173 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15174
15175 std::string response_data;
15176 rv = ReadTransaction(trans.get(), &response_data);
15177 EXPECT_EQ(OK, rv);
15178 EXPECT_EQ("hello world", response_data);
15179}
15180
15181TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915182 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215183 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915184 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215185 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415186
15187 HttpRequestInfo request;
15188 request.method = "POST";
15189 request.url = GURL("http://www.foo.com/");
15190 request.upload_data_stream = &upload_data_stream;
15191 request.load_flags = 0;
15192
danakj1fd259a02016-04-16 03:17:0915193 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15194 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115195 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415196 // Send headers successfully, but get an error while sending the body.
15197 MockWrite data_writes[] = {
15198 MockWrite("POST / HTTP/1.1\r\n"
15199 "Host: www.foo.com\r\n"
15200 "Connection: keep-alive\r\n"
15201 "Content-Length: 3\r\n\r\n"),
15202 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15203 };
15204
15205 MockRead data_reads[] = {
15206 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15207 MockRead("hello world"),
15208 MockRead(SYNCHRONOUS, OK),
15209 };
15210 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15211 arraysize(data_writes));
15212 session_deps_.socket_factory->AddSocketDataProvider(&data);
15213
15214 TestCompletionCallback callback;
15215
15216 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15217 EXPECT_EQ(ERR_IO_PENDING, rv);
15218
15219 rv = callback.WaitForResult();
15220 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415221}
15222
15223TEST_P(HttpNetworkTransactionTest,
15224 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915225 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215226 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915227 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215228 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415229
15230 HttpRequestInfo request;
15231 request.method = "POST";
15232 request.url = GURL("http://www.foo.com/");
15233 request.upload_data_stream = &upload_data_stream;
15234 request.load_flags = 0;
15235
danakj1fd259a02016-04-16 03:17:0915236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15237 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115238 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415239 // Send headers successfully, but get an error while sending the body.
15240 MockWrite data_writes[] = {
15241 MockWrite("POST / HTTP/1.1\r\n"
15242 "Host: www.foo.com\r\n"
15243 "Connection: keep-alive\r\n"
15244 "Content-Length: 3\r\n\r\n"),
15245 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15246 };
15247
15248 MockRead data_reads[] = {
15249 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15250 MockRead("HTTP/1.0 302 Redirect\r\n"),
15251 MockRead("Location: http://somewhere-else.com/\r\n"),
15252 MockRead("Content-Length: 0\r\n\r\n"),
15253 MockRead(SYNCHRONOUS, OK),
15254 };
15255 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15256 arraysize(data_writes));
15257 session_deps_.socket_factory->AddSocketDataProvider(&data);
15258
15259 TestCompletionCallback callback;
15260
15261 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15262 EXPECT_EQ(ERR_IO_PENDING, rv);
15263
15264 rv = callback.WaitForResult();
15265 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415266}
15267
15268TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915269 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215270 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915271 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215272 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415273
15274 HttpRequestInfo request;
15275 request.method = "POST";
15276 request.url = GURL("http://www.foo.com/");
15277 request.upload_data_stream = &upload_data_stream;
15278 request.load_flags = 0;
15279
danakj1fd259a02016-04-16 03:17:0915280 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15281 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115282 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415283 // Send headers successfully, but get an error while sending the body.
15284 MockWrite data_writes[] = {
15285 MockWrite("POST / HTTP/1.1\r\n"
15286 "Host: www.foo.com\r\n"
15287 "Connection: keep-alive\r\n"
15288 "Content-Length: 3\r\n\r\n"),
15289 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15290 };
15291
15292 MockRead data_reads[] = {
15293 MockRead("HTTP 0.9 rocks!"),
15294 MockRead(SYNCHRONOUS, OK),
15295 };
15296 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15297 arraysize(data_writes));
15298 session_deps_.socket_factory->AddSocketDataProvider(&data);
15299
15300 TestCompletionCallback callback;
15301
15302 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15303 EXPECT_EQ(ERR_IO_PENDING, rv);
15304
15305 rv = callback.WaitForResult();
15306 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415307}
15308
15309TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0915310 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215311 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915312 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215313 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415314
15315 HttpRequestInfo request;
15316 request.method = "POST";
15317 request.url = GURL("http://www.foo.com/");
15318 request.upload_data_stream = &upload_data_stream;
15319 request.load_flags = 0;
15320
danakj1fd259a02016-04-16 03:17:0915321 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15322 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115323 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415324 // Send headers successfully, but get an error while sending the body.
15325 MockWrite data_writes[] = {
15326 MockWrite("POST / HTTP/1.1\r\n"
15327 "Host: www.foo.com\r\n"
15328 "Connection: keep-alive\r\n"
15329 "Content-Length: 3\r\n\r\n"),
15330 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15331 };
15332
15333 MockRead data_reads[] = {
15334 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15335 MockRead(SYNCHRONOUS, OK),
15336 };
15337 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15338 arraysize(data_writes));
15339 session_deps_.socket_factory->AddSocketDataProvider(&data);
15340
15341 TestCompletionCallback callback;
15342
15343 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15344 EXPECT_EQ(ERR_IO_PENDING, rv);
15345
15346 rv = callback.WaitForResult();
15347 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415348}
15349
Adam Rice425cf122015-01-19 06:18:2415350// Verify that proxy headers are not sent to the destination server when
15351// establishing a tunnel for a secure WebSocket connection.
15352TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
15353 HttpRequestInfo request;
15354 request.method = "GET";
bncce36dca22015-04-21 22:11:2315355 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415356 AddWebSocketHeaders(&request.extra_headers);
15357
15358 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315359 session_deps_.proxy_service =
15360 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415361
danakj1fd259a02016-04-16 03:17:0915362 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415363
15364 // Since a proxy is configured, try to establish a tunnel.
15365 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715366 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15367 "Host: www.example.org:443\r\n"
15368 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415369
15370 // After calling trans->RestartWithAuth(), this is the request we should
15371 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1715372 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15373 "Host: www.example.org:443\r\n"
15374 "Proxy-Connection: keep-alive\r\n"
15375 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415376
rsleevidb16bb02015-11-12 23:47:1715377 MockWrite("GET / HTTP/1.1\r\n"
15378 "Host: www.example.org\r\n"
15379 "Connection: Upgrade\r\n"
15380 "Upgrade: websocket\r\n"
15381 "Origin: http://www.example.org\r\n"
15382 "Sec-WebSocket-Version: 13\r\n"
15383 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415384 };
15385
15386 // The proxy responds to the connect with a 407, using a persistent
15387 // connection.
15388 MockRead data_reads[] = {
15389 // No credentials.
15390 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15391 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415392 MockRead("Content-Length: 0\r\n"),
15393 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415394
15395 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15396
15397 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15398 MockRead("Upgrade: websocket\r\n"),
15399 MockRead("Connection: Upgrade\r\n"),
15400 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15401 };
15402
15403 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15404 arraysize(data_writes));
15405 session_deps_.socket_factory->AddSocketDataProvider(&data);
15406 SSLSocketDataProvider ssl(ASYNC, OK);
15407 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15408
danakj1fd259a02016-04-16 03:17:0915409 std::unique_ptr<HttpTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415410 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15411 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15412 trans->SetWebSocketHandshakeStreamCreateHelper(
15413 &websocket_stream_create_helper);
15414
15415 {
15416 TestCompletionCallback callback;
15417
15418 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15419 EXPECT_EQ(ERR_IO_PENDING, rv);
15420
15421 rv = callback.WaitForResult();
15422 EXPECT_EQ(OK, rv);
15423 }
15424
15425 const HttpResponseInfo* response = trans->GetResponseInfo();
15426 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215427 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415428 EXPECT_EQ(407, response->headers->response_code());
15429
15430 {
15431 TestCompletionCallback callback;
15432
15433 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15434 callback.callback());
15435 EXPECT_EQ(ERR_IO_PENDING, rv);
15436
15437 rv = callback.WaitForResult();
15438 EXPECT_EQ(OK, rv);
15439 }
15440
15441 response = trans->GetResponseInfo();
15442 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215443 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415444
15445 EXPECT_EQ(101, response->headers->response_code());
15446
15447 trans.reset();
15448 session->CloseAllConnections();
15449}
15450
15451// Verify that proxy headers are not sent to the destination server when
15452// establishing a tunnel for an insecure WebSocket connection.
15453// This requires the authentication info to be injected into the auth cache
15454// due to crbug.com/395064
15455// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
15456TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
15457 HttpRequestInfo request;
15458 request.method = "GET";
bncce36dca22015-04-21 22:11:2315459 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415460 AddWebSocketHeaders(&request.extra_headers);
15461
15462 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315463 session_deps_.proxy_service =
15464 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415465
danakj1fd259a02016-04-16 03:17:0915466 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415467
15468 MockWrite data_writes[] = {
15469 // Try to establish a tunnel for the WebSocket connection, with
15470 // credentials. Because WebSockets have a separate set of socket pools,
15471 // they cannot and will not use the same TCP/IP connection as the
15472 // preflight HTTP request.
15473 MockWrite(
bncce36dca22015-04-21 22:11:2315474 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15475 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415476 "Proxy-Connection: keep-alive\r\n"
15477 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15478
15479 MockWrite(
15480 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315481 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415482 "Connection: Upgrade\r\n"
15483 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315484 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415485 "Sec-WebSocket-Version: 13\r\n"
15486 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15487 };
15488
15489 MockRead data_reads[] = {
15490 // HTTP CONNECT with credentials.
15491 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15492
15493 // WebSocket connection established inside tunnel.
15494 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15495 MockRead("Upgrade: websocket\r\n"),
15496 MockRead("Connection: Upgrade\r\n"),
15497 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15498 };
15499
15500 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15501 arraysize(data_writes));
15502 session_deps_.socket_factory->AddSocketDataProvider(&data);
15503
15504 session->http_auth_cache()->Add(
15505 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
15506 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
15507
danakj1fd259a02016-04-16 03:17:0915508 std::unique_ptr<HttpTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415509 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15510 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15511 trans->SetWebSocketHandshakeStreamCreateHelper(
15512 &websocket_stream_create_helper);
15513
15514 TestCompletionCallback callback;
15515
15516 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15517 EXPECT_EQ(ERR_IO_PENDING, rv);
15518
15519 rv = callback.WaitForResult();
15520 EXPECT_EQ(OK, rv);
15521
15522 const HttpResponseInfo* response = trans->GetResponseInfo();
15523 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215524 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415525
15526 EXPECT_EQ(101, response->headers->response_code());
15527
15528 trans.reset();
15529 session->CloseAllConnections();
15530}
15531
sclittlefb249892015-09-10 21:33:2215532TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0915533 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215534 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915535 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215536 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215537
15538 HttpRequestInfo request;
15539 request.method = "POST";
15540 request.url = GURL("http://www.foo.com/");
15541 request.upload_data_stream = &upload_data_stream;
15542
danakj1fd259a02016-04-16 03:17:0915543 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15544 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2215545 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15546 MockWrite data_writes[] = {
15547 MockWrite("POST / HTTP/1.1\r\n"
15548 "Host: www.foo.com\r\n"
15549 "Connection: keep-alive\r\n"
15550 "Content-Length: 3\r\n\r\n"),
15551 MockWrite("foo"),
15552 };
15553
15554 MockRead data_reads[] = {
15555 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15556 MockRead(SYNCHRONOUS, OK),
15557 };
15558 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15559 arraysize(data_writes));
15560 session_deps_.socket_factory->AddSocketDataProvider(&data);
15561
15562 TestCompletionCallback callback;
15563
15564 EXPECT_EQ(ERR_IO_PENDING,
15565 trans->Start(&request, callback.callback(), BoundNetLog()));
15566 EXPECT_EQ(OK, callback.WaitForResult());
15567
15568 std::string response_data;
15569 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15570
15571 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15572 trans->GetTotalSentBytes());
15573 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15574 trans->GetTotalReceivedBytes());
15575}
15576
15577TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0915578 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215579 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915580 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215581 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215582
15583 HttpRequestInfo request;
15584 request.method = "POST";
15585 request.url = GURL("http://www.foo.com/");
15586 request.upload_data_stream = &upload_data_stream;
15587
danakj1fd259a02016-04-16 03:17:0915588 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15589 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2215590 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15591 MockWrite data_writes[] = {
15592 MockWrite("POST / HTTP/1.1\r\n"
15593 "Host: www.foo.com\r\n"
15594 "Connection: keep-alive\r\n"
15595 "Content-Length: 3\r\n\r\n"),
15596 MockWrite("foo"),
15597 };
15598
15599 MockRead data_reads[] = {
15600 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
15601 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15602 MockRead(SYNCHRONOUS, OK),
15603 };
15604 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15605 arraysize(data_writes));
15606 session_deps_.socket_factory->AddSocketDataProvider(&data);
15607
15608 TestCompletionCallback callback;
15609
15610 EXPECT_EQ(ERR_IO_PENDING,
15611 trans->Start(&request, callback.callback(), BoundNetLog()));
15612 EXPECT_EQ(OK, callback.WaitForResult());
15613
15614 std::string response_data;
15615 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15616
15617 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15618 trans->GetTotalSentBytes());
15619 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15620 trans->GetTotalReceivedBytes());
15621}
15622
15623TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2215624 ChunkedUploadDataStream upload_data_stream(0);
15625
15626 HttpRequestInfo request;
15627 request.method = "POST";
15628 request.url = GURL("http://www.foo.com/");
15629 request.upload_data_stream = &upload_data_stream;
15630
danakj1fd259a02016-04-16 03:17:0915631 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15632 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2215633 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15634 // Send headers successfully, but get an error while sending the body.
15635 MockWrite data_writes[] = {
15636 MockWrite("POST / HTTP/1.1\r\n"
15637 "Host: www.foo.com\r\n"
15638 "Connection: keep-alive\r\n"
15639 "Transfer-Encoding: chunked\r\n\r\n"),
15640 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
15641 };
15642
15643 MockRead data_reads[] = {
15644 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15645 MockRead(SYNCHRONOUS, OK),
15646 };
15647 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15648 arraysize(data_writes));
15649 session_deps_.socket_factory->AddSocketDataProvider(&data);
15650
15651 TestCompletionCallback callback;
15652
15653 EXPECT_EQ(ERR_IO_PENDING,
15654 trans->Start(&request, callback.callback(), BoundNetLog()));
15655
15656 base::RunLoop().RunUntilIdle();
15657 upload_data_stream.AppendData("f", 1, false);
15658
15659 base::RunLoop().RunUntilIdle();
15660 upload_data_stream.AppendData("oo", 2, true);
15661
15662 EXPECT_EQ(OK, callback.WaitForResult());
15663
15664 std::string response_data;
15665 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15666
15667 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15668 trans->GetTotalSentBytes());
15669 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15670 trans->GetTotalReceivedBytes());
15671}
15672
bncf4588402015-11-24 13:33:1815673TEST_P(HttpNetworkTransactionTest, EnableNPN) {
bncf4588402015-11-24 13:33:1815674 session_deps_.enable_npn = true;
15675
danakj1fd259a02016-04-16 03:17:0915676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncf4588402015-11-24 13:33:1815677 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
nharper8cdb0fb2016-04-22 21:34:5915678 HttpRequestInfo request;
15679 TestCompletionCallback callback;
15680 EXPECT_EQ(ERR_IO_PENDING,
15681 trans.Start(&request, callback.callback(), BoundNetLog()));
bncf4588402015-11-24 13:33:1815682
15683 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
15684 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15685 EXPECT_THAT(trans.server_ssl_config_.npn_protos,
15686 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15687}
15688
15689TEST_P(HttpNetworkTransactionTest, DisableNPN) {
bncf4588402015-11-24 13:33:1815690 session_deps_.enable_npn = false;
15691
danakj1fd259a02016-04-16 03:17:0915692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncf4588402015-11-24 13:33:1815693 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
nharper8cdb0fb2016-04-22 21:34:5915694 HttpRequestInfo request;
15695 TestCompletionCallback callback;
15696 EXPECT_EQ(ERR_IO_PENDING,
15697 trans.Start(&request, callback.callback(), BoundNetLog()));
bncf4588402015-11-24 13:33:1815698
15699 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
15700 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15701 EXPECT_TRUE(trans.server_ssl_config_.npn_protos.empty());
15702}
15703
nharperb7441ef2016-01-25 23:54:1415704#if !defined(OS_IOS)
15705TEST_P(HttpNetworkTransactionTest, TokenBindingSpdy) {
15706 const std::string https_url = "https://www.example.com";
15707 HttpRequestInfo request;
15708 request.url = GURL(https_url);
15709 request.method = "GET";
15710
15711 SSLSocketDataProvider ssl(ASYNC, OK);
15712 ssl.token_binding_negotiated = true;
15713 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
15714 ssl.SetNextProto(GetProtocol());
15715 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15716
danakj1fd259a02016-04-16 03:17:0915717 std::unique_ptr<SpdySerializedFrame> resp(
nharperb7441ef2016-01-25 23:54:1415718 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0915719 std::unique_ptr<SpdySerializedFrame> body(
bncb03b1092016-04-06 11:19:5515720 spdy_util_.ConstructSpdyBodyFrame(1, true));
nharperb7441ef2016-01-25 23:54:1415721 MockRead reads[] = {CreateMockRead(*resp), CreateMockRead(*body),
15722 MockRead(ASYNC, ERR_IO_PENDING)};
15723 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
15724 session_deps_.socket_factory->AddSocketDataProvider(&data);
15725 session_deps_.channel_id_service.reset(new ChannelIDService(
15726 new DefaultChannelIDStore(nullptr), base::ThreadTaskRunnerHandle::Get()));
danakj1fd259a02016-04-16 03:17:0915727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1415728
15729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15730 TestCompletionCallback callback;
15731 EXPECT_EQ(ERR_IO_PENDING,
15732 trans.Start(&request, callback.callback(), BoundNetLog()));
15733 base::MessageLoop::current()->RunUntilIdle();
15734
15735 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
15736 HttpRequestHeaders headers;
15737 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
15738 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
15739}
15740#endif // !defined(OS_IOS)
15741
[email protected]89ceba9a2009-03-21 03:46:0615742} // namespace net