blob: 6ff5d0bfd42baeb2715fedca94773aded2aac577 [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() +
330 "=\"www.example.com:443\"\r\n";
331 }
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);
9708 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9709 EXPECT_EQ(443, alternative_service_vector[0].port);
9710}
9711
bnc4f575852015-10-14 18:35:089712TEST_P(HttpNetworkTransactionTest, ClearAlternativeServices) {
bncf33fb31b2016-01-29 15:22:269713 session_deps_.enable_alternative_service_with_different_host = false;
bnc4f575852015-10-14 18:35:089714
9715 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:099716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc4f575852015-10-14 18:35:089717 HttpServerProperties& http_server_properties =
9718 *session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:469719 url::SchemeHostPort test_server("http", "www.example.org", 80);
bnc4f575852015-10-14 18:35:089720 AlternativeService alternative_service(QUIC, "", 80);
9721 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:469722 http_server_properties.SetAlternativeService(test_server, alternative_service,
9723 expiration);
bnc4f575852015-10-14 18:35:089724 AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469725 http_server_properties.GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:089726 EXPECT_EQ(1u, alternative_service_vector.size());
9727
9728 // Send a clear header.
9729 MockRead data_reads[] = {
9730 MockRead("HTTP/1.1 200 OK\r\n"),
9731 MockRead("Alt-Svc: clear\r\n"),
9732 MockRead("\r\n"),
9733 MockRead("hello world"),
9734 MockRead(SYNCHRONOUS, OK),
9735 };
9736 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
9737 session_deps_.socket_factory->AddSocketDataProvider(&data);
9738
9739 HttpRequestInfo request;
9740 request.method = "GET";
9741 request.url = GURL("http://www.example.org/");
9742 request.load_flags = 0;
9743
9744 TestCompletionCallback callback;
9745
danakj1fd259a02016-04-16 03:17:099746 std::unique_ptr<HttpTransaction> trans(
bnc4f575852015-10-14 18:35:089747 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9748
9749 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9750 EXPECT_EQ(OK, callback.GetResult(rv));
9751
9752 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529753 ASSERT_TRUE(response);
9754 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:089755 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9756 EXPECT_FALSE(response->was_fetched_via_spdy);
9757 EXPECT_FALSE(response->was_npn_negotiated);
9758
9759 std::string response_data;
9760 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9761 EXPECT_EQ("hello world", response_data);
9762
9763 alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469764 http_server_properties.GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:089765 EXPECT_TRUE(alternative_service_vector.empty());
9766}
9767
bncc958faa2015-07-31 18:14:529768TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:269769 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:529770
9771 MockRead data_reads[] = {
9772 MockRead("HTTP/1.1 200 OK\r\n"),
9773 MockRead("Alt-Svc: "),
9774 MockRead(GetAlternateProtocolFromParam()),
bnc44858c82015-10-16 11:57:219775 MockRead("=\"www.example.com:443\";p=\"1.0\","),
bnc3f0118e2016-02-02 15:42:229776 MockRead(GetAlternateProtocolFromParam()),
9777 MockRead("=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:529778 MockRead("hello world"),
9779 MockRead(SYNCHRONOUS, OK),
9780 };
9781
9782 HttpRequestInfo request;
9783 request.method = "GET";
9784 request.url = GURL("http://www.example.org/");
9785 request.load_flags = 0;
9786
9787 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9788
9789 session_deps_.socket_factory->AddSocketDataProvider(&data);
9790
9791 TestCompletionCallback callback;
9792
danakj1fd259a02016-04-16 03:17:099793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9794 std::unique_ptr<HttpTransaction> trans(
bncc958faa2015-07-31 18:14:529795 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9796
9797 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9798 EXPECT_EQ(ERR_IO_PENDING, rv);
9799
zhongyi3d4a55e72016-04-22 20:36:469800 url::SchemeHostPort test_server("http", "www.example.org", 80);
bncc958faa2015-07-31 18:14:529801 HttpServerProperties& http_server_properties =
9802 *session->http_server_properties();
9803 AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469804 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529805 EXPECT_TRUE(alternative_service_vector.empty());
9806
9807 EXPECT_EQ(OK, callback.WaitForResult());
9808
9809 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529810 ASSERT_TRUE(response);
9811 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:529812 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9813 EXPECT_FALSE(response->was_fetched_via_spdy);
9814 EXPECT_FALSE(response->was_npn_negotiated);
9815
9816 std::string response_data;
9817 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9818 EXPECT_EQ("hello world", response_data);
9819
9820 alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469821 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529822 ASSERT_EQ(2u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:389823 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:529824 alternative_service_vector[0].protocol);
9825 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9826 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc3f0118e2016-02-02 15:42:229827 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
9828 alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:529829 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
9830 EXPECT_EQ(1234, alternative_service_vector[1].port);
9831}
9832
bncf33fb31b2016-01-29 15:22:269833// When |enable_alternative_service_with_different_host| is false, do not
9834// observe alternative service entries that point to a different host.
bnc54ec34b72015-08-26 19:34:569835TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
bncf33fb31b2016-01-29 15:22:269836 session_deps_.enable_alternative_service_with_different_host = false;
bnc54ec34b72015-08-26 19:34:569837
9838 HttpRequestInfo request;
9839 request.method = "GET";
9840 request.url = GURL("http://www.example.org/");
9841 request.load_flags = 0;
9842
9843 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9844 StaticSocketDataProvider first_data;
9845 first_data.set_connect_data(mock_connect);
9846 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
9847
9848 MockRead data_reads[] = {
9849 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9850 MockRead(ASYNC, OK),
9851 };
9852 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
9853 nullptr, 0);
9854 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9855
danakj1fd259a02016-04-16 03:17:099856 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:569857
9858 base::WeakPtr<HttpServerProperties> http_server_properties =
9859 session->http_server_properties();
9860 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:389861 AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
9862 80);
bnc54ec34b72015-08-26 19:34:569863 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9864 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:469865 url::SchemeHostPort(request.url), alternative_service, expiration);
bnc54ec34b72015-08-26 19:34:569866
danakj1fd259a02016-04-16 03:17:099867 std::unique_ptr<HttpTransaction> trans(
bnc54ec34b72015-08-26 19:34:569868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9869 TestCompletionCallback callback;
9870
9871 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9872 // The connetion to origin was refused, and the alternative service should not
9873 // be used (even though mock data are there), therefore the request should
9874 // fail.
9875 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
9876}
9877
zhongyi48704c182015-12-07 07:52:029878TEST_P(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:469879 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:029880 HostPortPair alternative("alternative.example.org", 443);
9881 std::string origin_url = "https://origin.example.org:443";
9882 std::string alternative_url = "https://alternative.example.org:443";
9883
9884 // Negotiate HTTP/1.1 with alternative.example.org.
9885 SSLSocketDataProvider ssl(ASYNC, OK);
9886 ssl.SetNextProto(kProtoHTTP11);
9887 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9888
9889 // HTTP/1.1 data for request.
9890 MockWrite http_writes[] = {
9891 MockWrite("GET / HTTP/1.1\r\n"
9892 "Host: alternative.example.org\r\n"
9893 "Connection: keep-alive\r\n\r\n"),
9894 };
9895
9896 MockRead http_reads[] = {
9897 MockRead("HTTP/1.1 200 OK\r\n"
9898 "Content-Type: text/html; charset=iso-8859-1\r\n"
9899 "Content-Length: 40\r\n\r\n"
9900 "first HTTP/1.1 response from alternative"),
9901 };
9902 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
9903 http_writes, arraysize(http_writes));
9904 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
9905
9906 StaticSocketDataProvider data_refused;
9907 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
9908 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
9909
zhongyi3d4a55e72016-04-22 20:36:469910 // Set up a QUIC alternative service for server.
bncf33fb31b2016-01-29 15:22:269911 session_deps_.enable_alternative_service_with_different_host = false;
danakj1fd259a02016-04-16 03:17:099912 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zhongyi48704c182015-12-07 07:52:029913 base::WeakPtr<HttpServerProperties> http_server_properties =
9914 session->http_server_properties();
9915 AlternativeService alternative_service(QUIC, alternative);
9916 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:469917 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:509918 expiration);
zhongyi48704c182015-12-07 07:52:029919 // Mark the QUIC alternative service as broken.
9920 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
9921
danakj1fd259a02016-04-16 03:17:099922 std::unique_ptr<HttpTransaction> trans(
zhongyi48704c182015-12-07 07:52:029923 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9924 HttpRequestInfo request;
9925 request.method = "GET";
9926 request.url = GURL(origin_url);
9927 request.load_flags = 0;
9928 TestCompletionCallback callback;
9929 NetErrorDetails details;
9930 EXPECT_FALSE(details.quic_broken);
9931
9932 trans->Start(&request, callback.callback(), BoundNetLog());
9933 trans->PopulateNetErrorDetails(&details);
9934 EXPECT_TRUE(details.quic_broken);
9935}
9936
9937TEST_P(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:469938 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:029939 HostPortPair alternative1("alternative1.example.org", 443);
9940 HostPortPair alternative2("alternative2.example.org", 443);
9941 std::string origin_url = "https://origin.example.org:443";
9942 std::string alternative_url1 = "https://alternative1.example.org:443";
9943 std::string alternative_url2 = "https://alternative2.example.org:443";
9944
9945 // Negotiate HTTP/1.1 with alternative1.example.org.
9946 SSLSocketDataProvider ssl(ASYNC, OK);
9947 ssl.SetNextProto(kProtoHTTP11);
9948 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9949
9950 // HTTP/1.1 data for request.
9951 MockWrite http_writes[] = {
9952 MockWrite("GET / HTTP/1.1\r\n"
9953 "Host: alternative1.example.org\r\n"
9954 "Connection: keep-alive\r\n\r\n"),
9955 };
9956
9957 MockRead http_reads[] = {
9958 MockRead("HTTP/1.1 200 OK\r\n"
9959 "Content-Type: text/html; charset=iso-8859-1\r\n"
9960 "Content-Length: 40\r\n\r\n"
9961 "first HTTP/1.1 response from alternative1"),
9962 };
9963 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
9964 http_writes, arraysize(http_writes));
9965 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
9966
9967 StaticSocketDataProvider data_refused;
9968 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
9969 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
9970
bncf33fb31b2016-01-29 15:22:269971 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:099972 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zhongyi48704c182015-12-07 07:52:029973 base::WeakPtr<HttpServerProperties> http_server_properties =
9974 session->http_server_properties();
9975
zhongyi3d4a55e72016-04-22 20:36:469976 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:029977 AlternativeServiceInfoVector alternative_service_info_vector;
9978 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9979
9980 AlternativeService alternative_service1(QUIC, alternative1);
rchdc7b9052016-03-17 20:51:509981 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:029982 expiration);
9983 alternative_service_info_vector.push_back(alternative_service_info1);
9984 AlternativeService alternative_service2(QUIC, alternative2);
rchdc7b9052016-03-17 20:51:509985 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:029986 expiration);
9987 alternative_service_info_vector.push_back(alternative_service_info2);
9988
9989 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:469990 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:029991
9992 // Mark one of the QUIC alternative service as broken.
9993 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
9994
9995 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469996 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:029997
danakj1fd259a02016-04-16 03:17:099998 std::unique_ptr<HttpTransaction> trans(
zhongyi48704c182015-12-07 07:52:029999 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10000 HttpRequestInfo request;
10001 request.method = "GET";
10002 request.url = GURL(origin_url);
10003 request.load_flags = 0;
10004 TestCompletionCallback callback;
10005 NetErrorDetails details;
10006 EXPECT_FALSE(details.quic_broken);
10007
10008 trans->Start(&request, callback.callback(), BoundNetLog());
10009 trans->PopulateNetErrorDetails(&details);
10010 EXPECT_FALSE(details.quic_broken);
10011}
10012
[email protected]23e482282013-06-14 16:08:0210013TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310014 MarkBrokenAlternateProtocolAndFallback) {
bncf33fb31b2016-01-29 15:22:2610015 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]564b4912010-03-09 16:30:4210016
10017 HttpRequestInfo request;
10018 request.method = "GET";
bncce36dca22015-04-21 22:11:2310019 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210020 request.load_flags = 0;
10021
[email protected]d973e99a2012-02-17 21:02:3610022 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210023 StaticSocketDataProvider first_data;
10024 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710025 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:4210026
10027 MockRead data_reads[] = {
10028 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10029 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610030 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210031 };
10032 StaticSocketDataProvider second_data(
10033 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710034 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210035
danakj1fd259a02016-04-16 03:17:0910036 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210037
[email protected]30d4c022013-07-18 22:58:1610038 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310039 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610040 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110041 // Port must be < 1024, or the header will be ignored (since initial port was
10042 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010043 const AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810044 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bncd9b132e2015-07-08 05:16:1010045 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210046 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610047 http_server_properties->SetAlternativeService(server, alternative_service,
10048 expiration);
[email protected]564b4912010-03-09 16:30:4210049
danakj1fd259a02016-04-16 03:17:0910050 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010051 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110052 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210053
[email protected]49639fa2011-12-20 23:22:4110054 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:4210055 EXPECT_EQ(ERR_IO_PENDING, rv);
10056 EXPECT_EQ(OK, callback.WaitForResult());
10057
10058 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210059 ASSERT_TRUE(response);
10060 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210061 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10062
10063 std::string response_data;
10064 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10065 EXPECT_EQ("hello world", response_data);
10066
bncd9b132e2015-07-08 05:16:1010067 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610068 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010069 ASSERT_EQ(1u, alternative_service_vector.size());
10070 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10071 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10072 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210073}
10074
bnc55ff9da2015-08-19 18:42:3510075// Ensure that we are not allowed to redirect traffic via an alternate protocol
10076// to an unrestricted (port >= 1024) when the original traffic was on a
10077// restricted port (port < 1024). Ensure that we can redirect in all other
10078// cases.
[email protected]23e482282013-06-14 16:08:0210079TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310080 AlternateProtocolPortRestrictedBlocked) {
bncf33fb31b2016-01-29 15:22:2610081 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110082
10083 HttpRequestInfo restricted_port_request;
10084 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310085 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110086 restricted_port_request.load_flags = 0;
10087
[email protected]d973e99a2012-02-17 21:02:3610088 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110089 StaticSocketDataProvider first_data;
10090 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710091 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110092
10093 MockRead data_reads[] = {
10094 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10095 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610096 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110097 };
10098 StaticSocketDataProvider second_data(
10099 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710100 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110101
danakj1fd259a02016-04-16 03:17:0910102 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110103
[email protected]30d4c022013-07-18 22:58:1610104 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310105 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110106 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210107 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810108 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210109 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210110 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210111 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610112 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010113 expiration);
[email protected]3912662a32011-10-04 00:51:1110114
danakj1fd259a02016-04-16 03:17:0910115 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010116 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110117 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110118
[email protected]49639fa2011-12-20 23:22:4110119 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610120 &restricted_port_request,
10121 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110122 EXPECT_EQ(ERR_IO_PENDING, rv);
10123 // Invalid change to unrestricted port should fail.
10124 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:1910125}
[email protected]3912662a32011-10-04 00:51:1110126
bnc55ff9da2015-08-19 18:42:3510127// Ensure that we are allowed to redirect traffic via an alternate protocol to
10128// an unrestricted (port >= 1024) when the original traffic was on a restricted
10129// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:0210130TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:1910131 AlternateProtocolPortRestrictedPermitted) {
bncf33fb31b2016-01-29 15:22:2610132 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]bb88e1d32013-05-03 23:11:0710133 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910134
10135 HttpRequestInfo restricted_port_request;
10136 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310137 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910138 restricted_port_request.load_flags = 0;
10139
10140 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10141 StaticSocketDataProvider first_data;
10142 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710143 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910144
10145 MockRead data_reads[] = {
10146 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10147 MockRead("hello world"),
10148 MockRead(ASYNC, OK),
10149 };
10150 StaticSocketDataProvider second_data(
10151 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710152 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:1910153
danakj1fd259a02016-04-16 03:17:0910154 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910155
[email protected]30d4c022013-07-18 22:58:1610156 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910157 session->http_server_properties();
10158 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210159 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810160 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210161 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210162 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210163 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610164 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010165 expiration);
[email protected]c54c6962013-02-01 04:53:1910166
danakj1fd259a02016-04-16 03:17:0910167 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010168 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:1910169 TestCompletionCallback callback;
10170
10171 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:3610172 &restricted_port_request,
10173 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:1910174 // Change to unrestricted port should succeed.
10175 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110176}
10177
bnc55ff9da2015-08-19 18:42:3510178// Ensure that we are not allowed to redirect traffic via an alternate protocol
10179// to an unrestricted (port >= 1024) when the original traffic was on a
10180// restricted port (port < 1024). Ensure that we can redirect in all other
10181// cases.
[email protected]23e482282013-06-14 16:08:0210182TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310183 AlternateProtocolPortRestrictedAllowed) {
bncf33fb31b2016-01-29 15:22:2610184 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110185
10186 HttpRequestInfo restricted_port_request;
10187 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310188 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110189 restricted_port_request.load_flags = 0;
10190
[email protected]d973e99a2012-02-17 21:02:3610191 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110192 StaticSocketDataProvider first_data;
10193 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710194 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110195
10196 MockRead data_reads[] = {
10197 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10198 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610199 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110200 };
10201 StaticSocketDataProvider second_data(
10202 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710203 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110204
danakj1fd259a02016-04-16 03:17:0910205 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110206
[email protected]30d4c022013-07-18 22:58:1610207 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310208 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110209 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210210 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810211 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210212 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210213 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210214 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610215 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010216 expiration);
[email protected]3912662a32011-10-04 00:51:1110217
danakj1fd259a02016-04-16 03:17:0910218 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010219 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110220 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110221
[email protected]49639fa2011-12-20 23:22:4110222 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610223 &restricted_port_request,
10224 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110225 EXPECT_EQ(ERR_IO_PENDING, rv);
10226 // Valid change to restricted port should pass.
10227 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110228}
10229
bnc55ff9da2015-08-19 18:42:3510230// Ensure that we are not allowed to redirect traffic via an alternate protocol
10231// to an unrestricted (port >= 1024) when the original traffic was on a
10232// restricted port (port < 1024). Ensure that we can redirect in all other
10233// cases.
[email protected]23e482282013-06-14 16:08:0210234TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310235 AlternateProtocolPortUnrestrictedAllowed1) {
bncf33fb31b2016-01-29 15:22:2610236 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110237
10238 HttpRequestInfo unrestricted_port_request;
10239 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310240 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110241 unrestricted_port_request.load_flags = 0;
10242
[email protected]d973e99a2012-02-17 21:02:3610243 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110244 StaticSocketDataProvider first_data;
10245 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710246 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110247
10248 MockRead data_reads[] = {
10249 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10250 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610251 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110252 };
10253 StaticSocketDataProvider second_data(
10254 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710255 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110256
danakj1fd259a02016-04-16 03:17:0910257 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110258
[email protected]30d4c022013-07-18 22:58:1610259 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310260 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110261 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210262 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810263 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210264 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210265 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210266 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610267 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010268 expiration);
[email protected]3912662a32011-10-04 00:51:1110269
danakj1fd259a02016-04-16 03:17:0910270 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010271 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110272 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110273
[email protected]49639fa2011-12-20 23:22:4110274 int rv = trans->Start(
10275 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110276 EXPECT_EQ(ERR_IO_PENDING, rv);
10277 // Valid change to restricted port should pass.
10278 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110279}
10280
bnc55ff9da2015-08-19 18:42:3510281// Ensure that we are not allowed to redirect traffic via an alternate protocol
10282// to an unrestricted (port >= 1024) when the original traffic was on a
10283// restricted port (port < 1024). Ensure that we can redirect in all other
10284// cases.
[email protected]23e482282013-06-14 16:08:0210285TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310286 AlternateProtocolPortUnrestrictedAllowed2) {
bncf33fb31b2016-01-29 15:22:2610287 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110288
10289 HttpRequestInfo unrestricted_port_request;
10290 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310291 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110292 unrestricted_port_request.load_flags = 0;
10293
[email protected]d973e99a2012-02-17 21:02:3610294 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110295 StaticSocketDataProvider first_data;
10296 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710297 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110298
10299 MockRead data_reads[] = {
10300 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10301 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610302 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110303 };
10304 StaticSocketDataProvider second_data(
10305 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710306 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110307
danakj1fd259a02016-04-16 03:17:0910308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110309
[email protected]30d4c022013-07-18 22:58:1610310 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310311 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210312 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:2210313 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810314 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210315 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210316 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210317 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610318 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010319 expiration);
[email protected]3912662a32011-10-04 00:51:1110320
danakj1fd259a02016-04-16 03:17:0910321 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010322 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110323 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110324
[email protected]49639fa2011-12-20 23:22:4110325 int rv = trans->Start(
10326 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110327 EXPECT_EQ(ERR_IO_PENDING, rv);
10328 // Valid change to an unrestricted port should pass.
10329 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110330}
10331
bnc55ff9da2015-08-19 18:42:3510332// Ensure that we are not allowed to redirect traffic via an alternate protocol
10333// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10334// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:2310335TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bncf33fb31b2016-01-29 15:22:2610336 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]eb6234e2012-01-19 01:50:0210337
10338 HttpRequestInfo request;
10339 request.method = "GET";
bncce36dca22015-04-21 22:11:2310340 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210341 request.load_flags = 0;
10342
10343 // The alternate protocol request will error out before we attempt to connect,
10344 // so only the standard HTTP request will try to connect.
10345 MockRead data_reads[] = {
10346 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10347 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610348 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210349 };
10350 StaticSocketDataProvider data(
10351 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710352 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210353
danakj1fd259a02016-04-16 03:17:0910354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210355
[email protected]30d4c022013-07-18 22:58:1610356 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210357 session->http_server_properties();
10358 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:2210359 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810360 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210361 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210362 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210363 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610364 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210365
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]eb6234e2012-01-19 01:50:0210368 TestCompletionCallback callback;
10369
10370 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10371 EXPECT_EQ(ERR_IO_PENDING, rv);
10372 // The HTTP request should succeed.
10373 EXPECT_EQ(OK, callback.WaitForResult());
10374
[email protected]eb6234e2012-01-19 01:50:0210375 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210376 ASSERT_TRUE(response);
10377 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210378 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10379
10380 std::string response_data;
10381 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10382 EXPECT_EQ("hello world", response_data);
10383}
10384
[email protected]23e482282013-06-14 16:08:0210385TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc1c196c6e2016-05-28 13:51:4810386 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2ff8b312010-04-26 22:20:5410387
10388 HttpRequestInfo request;
10389 request.method = "GET";
bncce36dca22015-04-21 22:11:2310390 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410391 request.load_flags = 0;
10392
bnc1c196c6e2016-05-28 13:51:4810393 std::string alternative_service_http_header =
10394 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310395
[email protected]2ff8b312010-04-26 22:20:5410396 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210397 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810398 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210399 MockRead("\r\n"),
10400 MockRead("hello world"),
10401 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10402 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410403
10404 StaticSocketDataProvider first_transaction(
10405 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710406 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410407
[email protected]8ddf8322012-02-23 18:08:0610408 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810409 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310410 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10411 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710412 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410413
danakj1fd259a02016-04-16 03:17:0910414 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4910415 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310416 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410417
danakj1fd259a02016-04-16 03:17:0910418 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5510419 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910420 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5510421 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410422 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310423 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410424 };
10425
rch8e6c6c42015-05-01 14:05:1310426 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10427 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710428 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410429
[email protected]d973e99a2012-02-17 21:02:3610430 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510431 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10432 NULL, 0, NULL, 0);
10433 hanging_non_alternate_protocol_socket.set_connect_data(
10434 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710435 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510436 &hanging_non_alternate_protocol_socket);
10437
[email protected]49639fa2011-12-20 23:22:4110438 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410439
danakj1fd259a02016-04-16 03:17:0910440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10441 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010442 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410443
[email protected]49639fa2011-12-20 23:22:4110444 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410445 EXPECT_EQ(ERR_IO_PENDING, rv);
10446 EXPECT_EQ(OK, callback.WaitForResult());
10447
10448 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210449 ASSERT_TRUE(response);
10450 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410451 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10452
10453 std::string response_data;
10454 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10455 EXPECT_EQ("hello world", response_data);
10456
[email protected]90499482013-06-01 00:39:5010457 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410458
[email protected]49639fa2011-12-20 23:22:4110459 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410460 EXPECT_EQ(ERR_IO_PENDING, rv);
10461 EXPECT_EQ(OK, callback.WaitForResult());
10462
10463 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210464 ASSERT_TRUE(response);
10465 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210466 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310467 EXPECT_TRUE(response->was_fetched_via_spdy);
10468 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410469
10470 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10471 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410472}
10473
[email protected]23e482282013-06-14 16:08:0210474TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc1c196c6e2016-05-28 13:51:4810475 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2d6728692011-03-12 01:39:5510476
10477 HttpRequestInfo request;
10478 request.method = "GET";
bncce36dca22015-04-21 22:11:2310479 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510480 request.load_flags = 0;
10481
bnc1c196c6e2016-05-28 13:51:4810482 std::string alternative_service_http_header =
10483 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310484
[email protected]2d6728692011-03-12 01:39:5510485 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210486 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810487 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210488 MockRead("\r\n"),
10489 MockRead("hello world"),
10490 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10491 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510492 };
10493
10494 StaticSocketDataProvider first_transaction(
10495 data_reads, arraysize(data_reads), NULL, 0);
10496 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:0710497 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510498
[email protected]d973e99a2012-02-17 21:02:3610499 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810500 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10501 hanging_socket1.set_connect_data(never_finishing_connect);
[email protected]2d6728692011-03-12 01:39:5510502 // Socket 2 and 3 are the hanging Alternate-Protocol and
10503 // non-Alternate-Protocol jobs from the 2nd transaction.
mmenkecc2298e2015-12-07 18:20:1810504 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10505
10506 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10507 hanging_socket2.set_connect_data(never_finishing_connect);
10508 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510509
[email protected]8ddf8322012-02-23 18:08:0610510 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810511 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310512 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5210513 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0710514 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510515
danakj1fd259a02016-04-16 03:17:0910516 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4910517 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
danakj1fd259a02016-04-16 03:17:0910518 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4910519 spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:5510520 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310521 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:5510522 };
danakj1fd259a02016-04-16 03:17:0910523 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5510524 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910525 std::unique_ptr<SpdySerializedFrame> data1(
bncb03b1092016-04-06 11:19:5510526 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0910527 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5510528 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0910529 std::unique_ptr<SpdySerializedFrame> data2(
bncb03b1092016-04-06 11:19:5510530 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510531 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310532 CreateMockRead(*resp1, 2),
10533 CreateMockRead(*data1, 3),
10534 CreateMockRead(*resp2, 4),
10535 CreateMockRead(*data2, 5),
10536 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510537 };
10538
rch8e6c6c42015-05-01 14:05:1310539 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10540 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:5510541 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710542 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510543
10544 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
mmenkecc2298e2015-12-07 18:20:1810545 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10546 hanging_socket3.set_connect_data(never_finishing_connect);
10547 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510548
danakj1fd259a02016-04-16 03:17:0910549 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110550 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010551 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510552
[email protected]49639fa2011-12-20 23:22:4110553 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510554 EXPECT_EQ(ERR_IO_PENDING, rv);
10555 EXPECT_EQ(OK, callback1.WaitForResult());
10556
10557 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210558 ASSERT_TRUE(response);
10559 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510560 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10561
10562 std::string response_data;
10563 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10564 EXPECT_EQ("hello world", response_data);
10565
[email protected]49639fa2011-12-20 23:22:4110566 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5010567 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110568 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510569 EXPECT_EQ(ERR_IO_PENDING, rv);
10570
[email protected]49639fa2011-12-20 23:22:4110571 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5010572 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110573 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510574 EXPECT_EQ(ERR_IO_PENDING, rv);
10575
10576 EXPECT_EQ(OK, callback2.WaitForResult());
10577 EXPECT_EQ(OK, callback3.WaitForResult());
10578
10579 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5210580 ASSERT_TRUE(response);
10581 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210582 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5510583 EXPECT_TRUE(response->was_fetched_via_spdy);
10584 EXPECT_TRUE(response->was_npn_negotiated);
10585 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10586 EXPECT_EQ("hello!", response_data);
10587
10588 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5210589 ASSERT_TRUE(response);
10590 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210591 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5510592 EXPECT_TRUE(response->was_fetched_via_spdy);
10593 EXPECT_TRUE(response->was_npn_negotiated);
10594 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
10595 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5510596}
10597
bnc1c196c6e2016-05-28 13:51:4810598TEST_P(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
10599 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2d6728692011-03-12 01:39:5510600
10601 HttpRequestInfo request;
10602 request.method = "GET";
bnc1c196c6e2016-05-28 13:51:4810603 request.url = GURL("http://www.example.com/");
[email protected]2d6728692011-03-12 01:39:5510604 request.load_flags = 0;
10605
bnc1c196c6e2016-05-28 13:51:4810606 std::string alternative_service_http_header =
10607 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310608
[email protected]2d6728692011-03-12 01:39:5510609 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210610 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810611 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210612 MockRead("\r\n"),
10613 MockRead("hello world"),
10614 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10615 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510616 };
10617
10618 StaticSocketDataProvider first_transaction(
10619 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710620 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510621
[email protected]8ddf8322012-02-23 18:08:0610622 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810623 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0710624 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510625
[email protected]d973e99a2012-02-17 21:02:3610626 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510627 StaticSocketDataProvider hanging_alternate_protocol_socket(
10628 NULL, 0, NULL, 0);
10629 hanging_alternate_protocol_socket.set_connect_data(
10630 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710631 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510632 &hanging_alternate_protocol_socket);
10633
10634 // 2nd request is just a copy of the first one, over HTTP again.
mmenkecc2298e2015-12-07 18:20:1810635 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
10636 NULL, 0);
10637 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
[email protected]2d6728692011-03-12 01:39:5510638
[email protected]49639fa2011-12-20 23:22:4110639 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5510640
danakj1fd259a02016-04-16 03:17:0910641 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10642 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010643 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510644
[email protected]49639fa2011-12-20 23:22:4110645 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510646 EXPECT_EQ(ERR_IO_PENDING, rv);
10647 EXPECT_EQ(OK, callback.WaitForResult());
10648
10649 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210650 ASSERT_TRUE(response);
10651 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510652 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10653
10654 std::string response_data;
10655 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10656 EXPECT_EQ("hello world", response_data);
10657
[email protected]90499482013-06-01 00:39:5010658 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510659
[email protected]49639fa2011-12-20 23:22:4110660 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510661 EXPECT_EQ(ERR_IO_PENDING, rv);
10662 EXPECT_EQ(OK, callback.WaitForResult());
10663
10664 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210665 ASSERT_TRUE(response);
10666 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510667 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10668 EXPECT_FALSE(response->was_fetched_via_spdy);
10669 EXPECT_FALSE(response->was_npn_negotiated);
10670
10671 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10672 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5510673}
10674
[email protected]631f1322010-04-30 17:59:1110675class CapturingProxyResolver : public ProxyResolver {
10676 public:
sammce90c9212015-05-27 23:43:3510677 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2010678 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1110679
dchengb03027d2014-10-21 12:00:2010680 int GetProxyForURL(const GURL& url,
10681 ProxyInfo* results,
10682 const CompletionCallback& callback,
eroman9c8f4242016-02-29 21:16:5410683 RequestHandle* request,
dchengb03027d2014-10-21 12:00:2010684 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4010685 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
10686 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4210687 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1110688 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4210689 return OK;
[email protected]631f1322010-04-30 17:59:1110690 }
10691
eroman9c8f4242016-02-29 21:16:5410692 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
10693
10694 LoadState GetLoadState(RequestHandle request) const override {
10695 NOTREACHED();
10696 return LOAD_STATE_IDLE;
10697 }
10698
[email protected]24476402010-07-20 20:55:1710699 const std::vector<GURL>& resolved() const { return resolved_; }
10700
10701 private:
[email protected]631f1322010-04-30 17:59:1110702 std::vector<GURL> resolved_;
10703
10704 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
10705};
10706
sammce64b2362015-04-29 03:50:2310707class CapturingProxyResolverFactory : public ProxyResolverFactory {
10708 public:
10709 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
10710 : ProxyResolverFactory(false), resolver_(resolver) {}
10711
10712 int CreateProxyResolver(
10713 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0910714 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2310715 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0910716 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2310717 resolver->reset(new ForwardingProxyResolver(resolver_));
10718 return OK;
10719 }
10720
10721 private:
10722 ProxyResolver* resolver_;
10723};
10724
bnc1c196c6e2016-05-28 13:51:4810725TEST_P(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
10726 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]631f1322010-04-30 17:59:1110727
10728 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4210729 proxy_config.set_auto_detect(true);
10730 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1110731
sammc5dd160c2015-04-02 02:43:1310732 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:0710733 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0910734 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)),
10735 base::WrapUnique(
sammce64b2362015-04-29 03:50:2310736 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:3810737 NULL));
vishal.b62985ca92015-04-17 08:45:5110738 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710739 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1110740
10741 HttpRequestInfo request;
10742 request.method = "GET";
bncce36dca22015-04-21 22:11:2310743 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:1110744 request.load_flags = 0;
10745
bnc1c196c6e2016-05-28 13:51:4810746 std::string alternative_service_http_header =
10747 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310748
[email protected]631f1322010-04-30 17:59:1110749 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210750 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810751 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210752 MockRead("\r\n"),
10753 MockRead("hello world"),
10754 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10755 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1110756 };
10757
10758 StaticSocketDataProvider first_transaction(
10759 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710760 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1110761
[email protected]8ddf8322012-02-23 18:08:0610762 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810763 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310764 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5210765 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0710766 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1110767
danakj1fd259a02016-04-16 03:17:0910768 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4910769 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1110770 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310771 MockWrite(ASYNC, 0,
bnc1c196c6e2016-05-28 13:51:4810772 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10773 "Host: www.example.com:443\r\n"
rch8e6c6c42015-05-01 14:05:1310774 "Proxy-Connection: keep-alive\r\n\r\n"),
10775 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1110776 };
10777
[email protected]d911f1b2010-05-05 22:39:4210778 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10779
danakj1fd259a02016-04-16 03:17:0910780 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5510781 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910782 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5510783 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1110784 MockRead spdy_reads[] = {
mmenkee24011922015-12-17 22:12:5910785 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(*resp.get(), 3),
10786 CreateMockRead(*data.get(), 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1110787 };
10788
rch8e6c6c42015-05-01 14:05:1310789 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10790 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710791 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1110792
[email protected]d973e99a2012-02-17 21:02:3610793 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510794 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10795 NULL, 0, NULL, 0);
10796 hanging_non_alternate_protocol_socket.set_connect_data(
10797 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710798 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510799 &hanging_non_alternate_protocol_socket);
10800
[email protected]49639fa2011-12-20 23:22:4110801 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1110802
danakj1fd259a02016-04-16 03:17:0910803 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10804 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010805 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110806
[email protected]49639fa2011-12-20 23:22:4110807 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110808 EXPECT_EQ(ERR_IO_PENDING, rv);
10809 EXPECT_EQ(OK, callback.WaitForResult());
10810
10811 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210812 ASSERT_TRUE(response);
10813 ASSERT_TRUE(response->headers);
[email protected]631f1322010-04-30 17:59:1110814 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310815 EXPECT_FALSE(response->was_fetched_via_spdy);
10816 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110817
10818 std::string response_data;
10819 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10820 EXPECT_EQ("hello world", response_data);
10821
[email protected]90499482013-06-01 00:39:5010822 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110823
[email protected]49639fa2011-12-20 23:22:4110824 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110825 EXPECT_EQ(ERR_IO_PENDING, rv);
10826 EXPECT_EQ(OK, callback.WaitForResult());
10827
10828 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210829 ASSERT_TRUE(response);
10830 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210831 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310832 EXPECT_TRUE(response->was_fetched_via_spdy);
10833 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110834
10835 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10836 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1310837 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2310838 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310839 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2310840 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310841 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1110842
[email protected]029c83b62013-01-24 05:28:2010843 LoadTimingInfo load_timing_info;
10844 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10845 TestLoadTimingNotReusedWithPac(load_timing_info,
10846 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1110847}
[email protected]631f1322010-04-30 17:59:1110848
[email protected]23e482282013-06-14 16:08:0210849TEST_P(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4810850 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
10851 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2ff8b312010-04-26 22:20:5410852
10853 HttpRequestInfo request;
10854 request.method = "GET";
bncce36dca22015-04-21 22:11:2310855 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410856 request.load_flags = 0;
10857
bnc1c196c6e2016-05-28 13:51:4810858 std::string alternative_service_http_header =
10859 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310860
[email protected]2ff8b312010-04-26 22:20:5410861 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210862 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810863 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210864 MockRead("\r\n"),
10865 MockRead("hello world"),
10866 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5410867 };
10868
10869 StaticSocketDataProvider first_transaction(
10870 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710871 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410872
[email protected]8ddf8322012-02-23 18:08:0610873 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810874 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310875 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5210876 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0710877 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410878
danakj1fd259a02016-04-16 03:17:0910879 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4910880 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310881 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410882
danakj1fd259a02016-04-16 03:17:0910883 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5510884 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910885 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5510886 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410887 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310888 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410889 };
10890
rch8e6c6c42015-05-01 14:05:1310891 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10892 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710893 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410894
[email protected]83039bb2011-12-09 18:43:5510895 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410896
danakj1fd259a02016-04-16 03:17:0910897 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5410898
danakj1fd259a02016-04-16 03:17:0910899 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010900 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410901
[email protected]49639fa2011-12-20 23:22:4110902 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410903 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110904 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410905
10906 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210907 ASSERT_TRUE(response);
10908 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410909 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10910
10911 std::string response_data;
10912 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10913 EXPECT_EQ("hello world", response_data);
10914
10915 // Set up an initial SpdySession in the pool to reuse.
bnc1c196c6e2016-05-28 13:51:4810916 HostPortPair host_port_pair("www.example.com", 443);
[email protected]e6d017652013-05-17 18:01:4010917 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310918 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710919 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4210920 CreateSecureSpdySession(session.get(), key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3810921
[email protected]90499482013-06-01 00:39:5010922 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410923
[email protected]49639fa2011-12-20 23:22:4110924 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410925 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110926 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410927
10928 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210929 ASSERT_TRUE(response);
10930 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210931 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310932 EXPECT_TRUE(response->was_fetched_via_spdy);
10933 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410934
10935 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10936 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4210937}
10938
[email protected]044de0642010-06-17 10:42:1510939// GenerateAuthToken is a mighty big test.
10940// It tests all permutation of GenerateAuthToken behavior:
10941// - Synchronous and Asynchronous completion.
10942// - OK or error on completion.
10943// - Direct connection, non-authenticating proxy, and authenticating proxy.
10944// - HTTP or HTTPS backend (to include proxy tunneling).
10945// - Non-authenticating and authenticating backend.
10946//
[email protected]fe3b7dc2012-02-03 19:52:0910947// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1510948// problems generating an auth token for an authenticating proxy, we don't
10949// need to test all permutations of the backend server).
10950//
10951// The test proceeds by going over each of the configuration cases, and
10952// potentially running up to three rounds in each of the tests. The TestConfig
10953// specifies both the configuration for the test as well as the expectations
10954// for the results.
[email protected]23e482282013-06-14 16:08:0210955TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5010956 static const char kServer[] = "http://www.example.com";
10957 static const char kSecureServer[] = "https://www.example.com";
10958 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1510959 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
10960
10961 enum AuthTiming {
10962 AUTH_NONE,
10963 AUTH_SYNC,
10964 AUTH_ASYNC,
10965 };
10966
10967 const MockWrite kGet(
10968 "GET / HTTP/1.1\r\n"
10969 "Host: www.example.com\r\n"
10970 "Connection: keep-alive\r\n\r\n");
10971 const MockWrite kGetProxy(
10972 "GET http://www.example.com/ HTTP/1.1\r\n"
10973 "Host: www.example.com\r\n"
10974 "Proxy-Connection: keep-alive\r\n\r\n");
10975 const MockWrite kGetAuth(
10976 "GET / HTTP/1.1\r\n"
10977 "Host: www.example.com\r\n"
10978 "Connection: keep-alive\r\n"
10979 "Authorization: auth_token\r\n\r\n");
10980 const MockWrite kGetProxyAuth(
10981 "GET http://www.example.com/ HTTP/1.1\r\n"
10982 "Host: www.example.com\r\n"
10983 "Proxy-Connection: keep-alive\r\n"
10984 "Proxy-Authorization: auth_token\r\n\r\n");
10985 const MockWrite kGetAuthThroughProxy(
10986 "GET http://www.example.com/ HTTP/1.1\r\n"
10987 "Host: www.example.com\r\n"
10988 "Proxy-Connection: keep-alive\r\n"
10989 "Authorization: auth_token\r\n\r\n");
10990 const MockWrite kGetAuthWithProxyAuth(
10991 "GET http://www.example.com/ HTTP/1.1\r\n"
10992 "Host: www.example.com\r\n"
10993 "Proxy-Connection: keep-alive\r\n"
10994 "Proxy-Authorization: auth_token\r\n"
10995 "Authorization: auth_token\r\n\r\n");
10996 const MockWrite kConnect(
10997 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1710998 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1510999 "Proxy-Connection: keep-alive\r\n\r\n");
11000 const MockWrite kConnectProxyAuth(
11001 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711002 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511003 "Proxy-Connection: keep-alive\r\n"
11004 "Proxy-Authorization: auth_token\r\n\r\n");
11005
11006 const MockRead kSuccess(
11007 "HTTP/1.1 200 OK\r\n"
11008 "Content-Type: text/html; charset=iso-8859-1\r\n"
11009 "Content-Length: 3\r\n\r\n"
11010 "Yes");
11011 const MockRead kFailure(
11012 "Should not be called.");
11013 const MockRead kServerChallenge(
11014 "HTTP/1.1 401 Unauthorized\r\n"
11015 "WWW-Authenticate: Mock realm=server\r\n"
11016 "Content-Type: text/html; charset=iso-8859-1\r\n"
11017 "Content-Length: 14\r\n\r\n"
11018 "Unauthorized\r\n");
11019 const MockRead kProxyChallenge(
11020 "HTTP/1.1 407 Unauthorized\r\n"
11021 "Proxy-Authenticate: Mock realm=proxy\r\n"
11022 "Proxy-Connection: close\r\n"
11023 "Content-Type: text/html; charset=iso-8859-1\r\n"
11024 "Content-Length: 14\r\n\r\n"
11025 "Unauthorized\r\n");
11026 const MockRead kProxyConnected(
11027 "HTTP/1.1 200 Connection Established\r\n\r\n");
11028
11029 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11030 // no constructors, but the C++ compiler on Windows warns about
11031 // unspecified data in compound literals. So, moved to using constructors,
11032 // and TestRound's created with the default constructor should not be used.
11033 struct TestRound {
11034 TestRound()
11035 : expected_rv(ERR_UNEXPECTED),
11036 extra_write(NULL),
11037 extra_read(NULL) {
11038 }
11039 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11040 int expected_rv_arg)
11041 : write(write_arg),
11042 read(read_arg),
11043 expected_rv(expected_rv_arg),
11044 extra_write(NULL),
11045 extra_read(NULL) {
11046 }
11047 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11048 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111049 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511050 : write(write_arg),
11051 read(read_arg),
11052 expected_rv(expected_rv_arg),
11053 extra_write(extra_write_arg),
11054 extra_read(extra_read_arg) {
11055 }
11056 MockWrite write;
11057 MockRead read;
11058 int expected_rv;
11059 const MockWrite* extra_write;
11060 const MockRead* extra_read;
11061 };
11062
11063 static const int kNoSSL = 500;
11064
11065 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5111066 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511067 AuthTiming proxy_auth_timing;
11068 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5111069 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511070 AuthTiming server_auth_timing;
11071 int server_auth_rv;
11072 int num_auth_rounds;
11073 int first_ssl_round;
11074 TestRound rounds[3];
11075 } test_configs[] = {
11076 // Non-authenticating HTTP server with a direct connection.
11077 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11078 { TestRound(kGet, kSuccess, OK)}},
11079 // Authenticating HTTP server with a direct connection.
11080 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11081 { TestRound(kGet, kServerChallenge, OK),
11082 TestRound(kGetAuth, kSuccess, OK)}},
11083 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11084 { TestRound(kGet, kServerChallenge, OK),
11085 TestRound(kGetAuth, kFailure, kAuthErr)}},
11086 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11087 { TestRound(kGet, kServerChallenge, OK),
11088 TestRound(kGetAuth, kSuccess, OK)}},
11089 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11090 { TestRound(kGet, kServerChallenge, OK),
11091 TestRound(kGetAuth, kFailure, kAuthErr)}},
11092 // Non-authenticating HTTP server through a non-authenticating proxy.
11093 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11094 { TestRound(kGetProxy, kSuccess, OK)}},
11095 // Authenticating HTTP server through a non-authenticating proxy.
11096 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11097 { TestRound(kGetProxy, kServerChallenge, OK),
11098 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11099 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11100 { TestRound(kGetProxy, kServerChallenge, OK),
11101 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11102 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11103 { TestRound(kGetProxy, kServerChallenge, OK),
11104 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11105 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11106 { TestRound(kGetProxy, kServerChallenge, OK),
11107 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11108 // Non-authenticating HTTP server through an authenticating proxy.
11109 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11110 { TestRound(kGetProxy, kProxyChallenge, OK),
11111 TestRound(kGetProxyAuth, kSuccess, OK)}},
11112 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11113 { TestRound(kGetProxy, kProxyChallenge, OK),
11114 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11115 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11116 { TestRound(kGetProxy, kProxyChallenge, OK),
11117 TestRound(kGetProxyAuth, kSuccess, OK)}},
11118 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11119 { TestRound(kGetProxy, kProxyChallenge, OK),
11120 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11121 // Authenticating HTTP server through an authenticating proxy.
11122 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11123 { TestRound(kGetProxy, kProxyChallenge, OK),
11124 TestRound(kGetProxyAuth, kServerChallenge, OK),
11125 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11126 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11127 { TestRound(kGetProxy, kProxyChallenge, OK),
11128 TestRound(kGetProxyAuth, kServerChallenge, OK),
11129 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11130 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11131 { TestRound(kGetProxy, kProxyChallenge, OK),
11132 TestRound(kGetProxyAuth, kServerChallenge, OK),
11133 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11134 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11135 { TestRound(kGetProxy, kProxyChallenge, OK),
11136 TestRound(kGetProxyAuth, kServerChallenge, OK),
11137 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11138 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11139 { TestRound(kGetProxy, kProxyChallenge, OK),
11140 TestRound(kGetProxyAuth, kServerChallenge, OK),
11141 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11142 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11143 { TestRound(kGetProxy, kProxyChallenge, OK),
11144 TestRound(kGetProxyAuth, kServerChallenge, OK),
11145 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11146 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11147 { TestRound(kGetProxy, kProxyChallenge, OK),
11148 TestRound(kGetProxyAuth, kServerChallenge, OK),
11149 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11150 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11151 { TestRound(kGetProxy, kProxyChallenge, OK),
11152 TestRound(kGetProxyAuth, kServerChallenge, OK),
11153 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11154 // Non-authenticating HTTPS server with a direct connection.
11155 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11156 { TestRound(kGet, kSuccess, OK)}},
11157 // Authenticating HTTPS server with a direct connection.
11158 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11159 { TestRound(kGet, kServerChallenge, OK),
11160 TestRound(kGetAuth, kSuccess, OK)}},
11161 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11162 { TestRound(kGet, kServerChallenge, OK),
11163 TestRound(kGetAuth, kFailure, kAuthErr)}},
11164 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11165 { TestRound(kGet, kServerChallenge, OK),
11166 TestRound(kGetAuth, kSuccess, OK)}},
11167 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11168 { TestRound(kGet, kServerChallenge, OK),
11169 TestRound(kGetAuth, kFailure, kAuthErr)}},
11170 // Non-authenticating HTTPS server with a non-authenticating proxy.
11171 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11172 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11173 // Authenticating HTTPS server through a non-authenticating proxy.
11174 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11175 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11176 TestRound(kGetAuth, kSuccess, OK)}},
11177 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11178 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11179 TestRound(kGetAuth, kFailure, kAuthErr)}},
11180 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11181 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11182 TestRound(kGetAuth, kSuccess, OK)}},
11183 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11184 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11185 TestRound(kGetAuth, kFailure, kAuthErr)}},
11186 // Non-Authenticating HTTPS server through an authenticating proxy.
11187 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11188 { TestRound(kConnect, kProxyChallenge, OK),
11189 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11190 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11191 { TestRound(kConnect, kProxyChallenge, OK),
11192 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11193 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11194 { TestRound(kConnect, kProxyChallenge, OK),
11195 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11196 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11197 { TestRound(kConnect, kProxyChallenge, OK),
11198 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11199 // Authenticating HTTPS server through an authenticating proxy.
11200 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11201 { TestRound(kConnect, kProxyChallenge, OK),
11202 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11203 &kGet, &kServerChallenge),
11204 TestRound(kGetAuth, kSuccess, OK)}},
11205 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11206 { TestRound(kConnect, kProxyChallenge, OK),
11207 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11208 &kGet, &kServerChallenge),
11209 TestRound(kGetAuth, kFailure, kAuthErr)}},
11210 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11211 { TestRound(kConnect, kProxyChallenge, OK),
11212 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11213 &kGet, &kServerChallenge),
11214 TestRound(kGetAuth, kSuccess, OK)}},
11215 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11216 { TestRound(kConnect, kProxyChallenge, OK),
11217 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11218 &kGet, &kServerChallenge),
11219 TestRound(kGetAuth, kFailure, kAuthErr)}},
11220 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11221 { TestRound(kConnect, kProxyChallenge, OK),
11222 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11223 &kGet, &kServerChallenge),
11224 TestRound(kGetAuth, kSuccess, OK)}},
11225 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11226 { TestRound(kConnect, kProxyChallenge, OK),
11227 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11228 &kGet, &kServerChallenge),
11229 TestRound(kGetAuth, kFailure, kAuthErr)}},
11230 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11231 { TestRound(kConnect, kProxyChallenge, OK),
11232 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11233 &kGet, &kServerChallenge),
11234 TestRound(kGetAuth, kSuccess, OK)}},
11235 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11236 { TestRound(kConnect, kProxyChallenge, OK),
11237 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11238 &kGet, &kServerChallenge),
11239 TestRound(kGetAuth, kFailure, kAuthErr)}},
11240 };
11241
viettrungluue4a8b882014-10-16 06:17:3811242 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0811243 HttpAuthHandlerMock::Factory* auth_factory(
11244 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711245 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4911246 SSLInfo empty_ssl_info;
[email protected]044de0642010-06-17 10:42:1511247 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2611248
11249 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1511250 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0811251 for (int n = 0; n < 2; n++) {
11252 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11253 std::string auth_challenge = "Mock realm=proxy";
11254 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2411255 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11256 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0811257 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
asanka5ffd5d72016-03-23 16:20:4911258 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811259 auth_handler->SetGenerateExpectation(
11260 test_config.proxy_auth_timing == AUTH_ASYNC,
11261 test_config.proxy_auth_rv);
11262 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11263 }
[email protected]044de0642010-06-17 10:42:1511264 }
11265 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0011266 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1511267 std::string auth_challenge = "Mock realm=server";
11268 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2411269 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11270 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1511271 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911272 empty_ssl_info, origin, BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511273 auth_handler->SetGenerateExpectation(
11274 test_config.server_auth_timing == AUTH_ASYNC,
11275 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0811276 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1511277 }
11278 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0311279 session_deps_.proxy_service =
11280 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1511281 } else {
rdsmith82957ad2015-09-16 19:42:0311282 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1511283 }
11284
11285 HttpRequestInfo request;
11286 request.method = "GET";
11287 request.url = GURL(test_config.server_url);
11288 request.load_flags = 0;
11289
danakj1fd259a02016-04-16 03:17:0911290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1511291
rchcb68dc62015-05-21 04:45:3611292 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
11293
11294 std::vector<std::vector<MockRead>> mock_reads(1);
11295 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1511296 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11297 const TestRound& read_write_round = test_config.rounds[round];
11298
11299 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3611300 mock_reads.back().push_back(read_write_round.read);
11301 mock_writes.back().push_back(read_write_round.write);
11302
11303 // kProxyChallenge uses Proxy-Connection: close which means that the
11304 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5411305 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3611306 mock_reads.push_back(std::vector<MockRead>());
11307 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1511308 }
11309
rchcb68dc62015-05-21 04:45:3611310 if (read_write_round.extra_read) {
11311 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1511312 }
rchcb68dc62015-05-21 04:45:3611313 if (read_write_round.extra_write) {
11314 mock_writes.back().push_back(*read_write_round.extra_write);
11315 }
[email protected]044de0642010-06-17 10:42:1511316
11317 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1511318 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0711319 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1511320 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3611321 }
[email protected]044de0642010-06-17 10:42:1511322
danakj1fd259a02016-04-16 03:17:0911323 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3611324 for (size_t i = 0; i < mock_reads.size(); ++i) {
danakj1fd259a02016-04-16 03:17:0911325 data_providers.push_back(base::WrapUnique(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5411326 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3211327 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3611328 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3211329 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3611330 }
11331
mmenkecc2298e2015-12-07 18:20:1811332 // Transaction must be created after DataProviders, so it's destroyed before
11333 // they are as well.
11334 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11335
rchcb68dc62015-05-21 04:45:3611336 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11337 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1511338 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4111339 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1511340 int rv;
11341 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4111342 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511343 } else {
[email protected]49639fa2011-12-20 23:22:4111344 rv = trans.RestartWithAuth(
11345 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1511346 }
11347 if (rv == ERR_IO_PENDING)
11348 rv = callback.WaitForResult();
11349
11350 // Compare results with expected data.
11351 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5011352 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5511353 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1511354 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
11355 continue;
11356 }
11357 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5211358 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511359 } else {
wezca1070932016-05-26 20:30:5211360 EXPECT_FALSE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511361 }
11362 }
[email protected]e5ae96a2010-04-14 20:12:4511363 }
11364}
11365
[email protected]23e482282013-06-14 16:08:0211366TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1411367 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1411368 HttpAuthHandlerMock::Factory* auth_factory(
11369 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711370 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0311371 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0711372 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
11373 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1411374
11375 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11376 auth_handler->set_connection_based(true);
11377 std::string auth_challenge = "Mock realm=server";
11378 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2411379 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11380 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4911381 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1411382 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911383 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811384 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1411385
[email protected]c871bce92010-07-15 21:51:1411386 int rv = OK;
11387 const HttpResponseInfo* response = NULL;
11388 HttpRequestInfo request;
11389 request.method = "GET";
11390 request.url = origin;
11391 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2711392
danakj1fd259a02016-04-16 03:17:0911393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1011394
11395 // Use a TCP Socket Pool with only one connection per group. This is used
11396 // to validate that the TCP socket is not released to the pool between
11397 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4211398 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2811399 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1011400 50, // Max sockets for pool
11401 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2111402 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
11403 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0911404 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4411405 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0211406 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4811407 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1011408
danakj1fd259a02016-04-16 03:17:0911409 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011410 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111411 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1411412
11413 const MockWrite kGet(
11414 "GET / HTTP/1.1\r\n"
11415 "Host: www.example.com\r\n"
11416 "Connection: keep-alive\r\n\r\n");
11417 const MockWrite kGetAuth(
11418 "GET / HTTP/1.1\r\n"
11419 "Host: www.example.com\r\n"
11420 "Connection: keep-alive\r\n"
11421 "Authorization: auth_token\r\n\r\n");
11422
11423 const MockRead kServerChallenge(
11424 "HTTP/1.1 401 Unauthorized\r\n"
11425 "WWW-Authenticate: Mock realm=server\r\n"
11426 "Content-Type: text/html; charset=iso-8859-1\r\n"
11427 "Content-Length: 14\r\n\r\n"
11428 "Unauthorized\r\n");
11429 const MockRead kSuccess(
11430 "HTTP/1.1 200 OK\r\n"
11431 "Content-Type: text/html; charset=iso-8859-1\r\n"
11432 "Content-Length: 3\r\n\r\n"
11433 "Yes");
11434
11435 MockWrite writes[] = {
11436 // First round
11437 kGet,
11438 // Second round
11439 kGetAuth,
11440 // Third round
11441 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3011442 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1011443 kGetAuth,
11444 // Competing request
11445 kGet,
[email protected]c871bce92010-07-15 21:51:1411446 };
11447 MockRead reads[] = {
11448 // First round
11449 kServerChallenge,
11450 // Second round
11451 kServerChallenge,
11452 // Third round
[email protected]eca50e122010-09-11 14:03:3011453 kServerChallenge,
11454 // Fourth round
[email protected]c871bce92010-07-15 21:51:1411455 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1011456 // Competing response
11457 kSuccess,
[email protected]c871bce92010-07-15 21:51:1411458 };
11459 StaticSocketDataProvider data_provider(reads, arraysize(reads),
11460 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0711461 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1411462
thestig9d3bb0c2015-01-24 00:49:5111463 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1011464
11465 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1411466 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111467 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1411468 if (rv == ERR_IO_PENDING)
11469 rv = callback.WaitForResult();
11470 EXPECT_EQ(OK, rv);
11471 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211472 ASSERT_TRUE(response);
11473 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811474 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411475
[email protected]7ef4cbbb2011-02-06 11:19:1011476 // In between rounds, another request comes in for the same domain.
11477 // It should not be able to grab the TCP socket that trans has already
11478 // claimed.
danakj1fd259a02016-04-16 03:17:0911479 std::unique_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5011480 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111481 TestCompletionCallback callback_compete;
11482 rv = trans_compete->Start(
11483 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1011484 EXPECT_EQ(ERR_IO_PENDING, rv);
11485 // callback_compete.WaitForResult at this point would stall forever,
11486 // since the HttpNetworkTransaction does not release the request back to
11487 // the pool until after authentication completes.
11488
11489 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1411490 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111491 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411492 if (rv == ERR_IO_PENDING)
11493 rv = callback.WaitForResult();
11494 EXPECT_EQ(OK, rv);
11495 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211496 ASSERT_TRUE(response);
11497 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811498 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411499
[email protected]7ef4cbbb2011-02-06 11:19:1011500 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1411501 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111502 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411503 if (rv == ERR_IO_PENDING)
11504 rv = callback.WaitForResult();
11505 EXPECT_EQ(OK, rv);
11506 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211507 ASSERT_TRUE(response);
11508 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811509 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3011510
[email protected]7ef4cbbb2011-02-06 11:19:1011511 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3011512 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111513 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3011514 if (rv == ERR_IO_PENDING)
11515 rv = callback.WaitForResult();
11516 EXPECT_EQ(OK, rv);
11517 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211518 ASSERT_TRUE(response);
11519 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811520 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011521
11522 // Read the body since the fourth round was successful. This will also
11523 // release the socket back to the pool.
11524 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5011525 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011526 if (rv == ERR_IO_PENDING)
11527 rv = callback.WaitForResult();
11528 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011529 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011530 EXPECT_EQ(0, rv);
11531 // There are still 0 idle sockets, since the trans_compete transaction
11532 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2811533 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011534
11535 // The competing request can now finish. Wait for the headers and then
11536 // read the body.
11537 rv = callback_compete.WaitForResult();
11538 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5011539 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011540 if (rv == ERR_IO_PENDING)
11541 rv = callback.WaitForResult();
11542 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011543 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011544 EXPECT_EQ(0, rv);
11545
11546 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2811547 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411548}
11549
[email protected]65041fa2010-05-21 06:56:5311550// This tests the case that a request is issued via http instead of spdy after
11551// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0211552TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bncf33fb31b2016-01-29 15:22:2611553 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d7599122014-05-24 03:37:2311554
[email protected]65041fa2010-05-21 06:56:5311555 HttpRequestInfo request;
11556 request.method = "GET";
bncce36dca22015-04-21 22:11:2311557 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5311558 request.load_flags = 0;
11559
11560 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2311561 MockWrite(
11562 "GET / HTTP/1.1\r\n"
11563 "Host: www.example.org\r\n"
11564 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5311565 };
11566
bnc1c196c6e2016-05-28 13:51:4811567 std::string alternative_service_http_header =
11568 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4311569
[email protected]65041fa2010-05-21 06:56:5311570 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211571 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4811572 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5211573 MockRead("\r\n"),
11574 MockRead("hello world"),
11575 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5311576 };
11577
[email protected]8ddf8322012-02-23 18:08:0611578 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4811579 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5311580
[email protected]bb88e1d32013-05-03 23:11:0711581 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5311582
11583 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11584 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711585 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5311586
[email protected]49639fa2011-12-20 23:22:4111587 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5311588
danakj1fd259a02016-04-16 03:17:0911589 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11590 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011591 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5311592
[email protected]49639fa2011-12-20 23:22:4111593 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5311594
11595 EXPECT_EQ(ERR_IO_PENDING, rv);
11596 EXPECT_EQ(OK, callback.WaitForResult());
11597
11598 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211599 ASSERT_TRUE(response);
11600 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5311601 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11602
11603 std::string response_data;
11604 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11605 EXPECT_EQ("hello world", response_data);
11606
11607 EXPECT_FALSE(response->was_fetched_via_spdy);
11608 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5311609}
[email protected]26ef6582010-06-24 02:30:4711610
bnc55ff9da2015-08-19 18:42:3511611// Simulate the SSL handshake completing with an NPN negotiation followed by an
11612// immediate server closing of the socket.
11613// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0211614TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bncf33fb31b2016-01-29 15:22:2611615 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]26ef6582010-06-24 02:30:4711616
11617 HttpRequestInfo request;
11618 request.method = "GET";
bncce36dca22015-04-21 22:11:2311619 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4711620 request.load_flags = 0;
11621
[email protected]8ddf8322012-02-23 18:08:0611622 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811623 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0711624 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4711625
danakj1fd259a02016-04-16 03:17:0911626 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911627 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1311628 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4711629
11630 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611631 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4711632 };
11633
rch8e6c6c42015-05-01 14:05:1311634 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11635 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711636 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4711637
[email protected]49639fa2011-12-20 23:22:4111638 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4711639
danakj1fd259a02016-04-16 03:17:0911640 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11641 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011642 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4711643
[email protected]49639fa2011-12-20 23:22:4111644 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4711645 EXPECT_EQ(ERR_IO_PENDING, rv);
11646 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4711647}
[email protected]65d34382010-07-01 18:12:2611648
[email protected]795cbf82013-07-22 09:37:2711649// A subclass of HttpAuthHandlerMock that records the request URL when
11650// it gets it. This is needed since the auth handler may get destroyed
11651// before we get a chance to query it.
11652class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
11653 public:
11654 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
11655
dchengb03027d2014-10-21 12:00:2011656 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2711657
11658 protected:
dchengb03027d2014-10-21 12:00:2011659 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
11660 const HttpRequestInfo* request,
11661 const CompletionCallback& callback,
11662 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2711663 *url_ = request->url;
11664 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
11665 credentials, request, callback, auth_token);
11666 }
11667
11668 private:
11669 GURL* url_;
11670};
11671
bnc55ff9da2015-08-19 18:42:3511672// This test ensures that the URL passed into the proxy is upgraded to https
11673// when doing an Alternate Protocol upgrade.
bnc1c196c6e2016-05-28 13:51:4811674TEST_P(HttpNetworkTransactionTest, SpdyAlternativeServiceThroughProxy) {
bncf33fb31b2016-01-29 15:22:2611675 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]f45c1ee2010-08-03 00:54:3011676
rdsmith82957ad2015-09-16 19:42:0311677 session_deps_.proxy_service =
11678 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111679 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711680 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2711681 GURL request_url;
11682 {
11683 HttpAuthHandlerMock::Factory* auth_factory =
11684 new HttpAuthHandlerMock::Factory();
11685 UrlRecordingHttpAuthHandlerMock* auth_handler =
11686 new UrlRecordingHttpAuthHandlerMock(&request_url);
11687 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11688 auth_factory->set_do_init_from_challenge(true);
11689 session_deps_.http_auth_handler_factory.reset(auth_factory);
11690 }
[email protected]f45c1ee2010-08-03 00:54:3011691
11692 HttpRequestInfo request;
11693 request.method = "GET";
bncce36dca22015-04-21 22:11:2311694 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3011695 request.load_flags = 0;
11696
11697 // First round goes unauthenticated through the proxy.
11698 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2311699 MockWrite(
11700 "GET http://www.example.org/ HTTP/1.1\r\n"
11701 "Host: www.example.org\r\n"
11702 "Proxy-Connection: keep-alive\r\n"
11703 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011704 };
11705 MockRead data_reads_1[] = {
bnc1c196c6e2016-05-28 13:51:4811706 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11707 MockRead("HTTP/1.1 200 OK\r\n"),
11708 MockRead("Alt-Svc: "),
11709 MockRead(GetAlternateProtocolFromParam()),
11710 MockRead("=\":443\"\r\n"),
11711 MockRead("Proxy-Connection: close\r\n"),
11712 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011713 };
11714 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
11715 data_writes_1, arraysize(data_writes_1));
11716
bncce36dca22015-04-21 22:11:2311717 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3011718 // Alternate-Protocol announcement in the first round. It fails due
11719 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2311720 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5911721 // Proxy-Authorization headers. There is then a SPDY request round.
11722 //
[email protected]fe3b7dc2012-02-03 19:52:0911723 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
11724 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
11725 // does a Disconnect and Connect on the same socket, rather than trying
11726 // to obtain a new one.
11727 //
[email protected]394816e92010-08-03 07:38:5911728 // NOTE: Originally, the proxy response to the second CONNECT request
11729 // simply returned another 407 so the unit test could skip the SSL connection
11730 // establishment and SPDY framing issues. Alas, the
11731 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3011732 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5911733
danakj1fd259a02016-04-16 03:17:0911734 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911735 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
danakj1fd259a02016-04-16 03:17:0911736 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5511737 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0911738 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5511739 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3011740
[email protected]394816e92010-08-03 07:38:5911741 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2311742 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311743 MockWrite(ASYNC, 0,
11744 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711745 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311746 "Proxy-Connection: keep-alive\r\n"
11747 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911748
bncce36dca22015-04-21 22:11:2311749 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1311750 MockWrite(ASYNC, 2,
11751 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711752 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311753 "Proxy-Connection: keep-alive\r\n"
11754 "Proxy-Authorization: auth_token\r\n"
11755 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011756
bncce36dca22015-04-21 22:11:2311757 // SPDY request
rch8e6c6c42015-05-01 14:05:1311758 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3011759 };
[email protected]394816e92010-08-03 07:38:5911760 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1311761 // First connection attempt fails
mmenkee71e15332015-10-07 16:39:5411762 MockRead(ASYNC, 1,
11763 "HTTP/1.1 407 Unauthorized\r\n"
11764 "Proxy-Authenticate: Mock\r\n"
11765 "Content-Length: 0\r\n"
11766 "Proxy-Connection: keep-alive\r\n"
11767 "\r\n"),
[email protected]394816e92010-08-03 07:38:5911768
rch8e6c6c42015-05-01 14:05:1311769 // Second connection attempt passes
mmenkee71e15332015-10-07 16:39:5411770 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5911771
rch8e6c6c42015-05-01 14:05:1311772 // SPDY response
mmenkee71e15332015-10-07 16:39:5411773 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1311774 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5911775 };
rch8e6c6c42015-05-01 14:05:1311776 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
11777 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3011778
[email protected]8ddf8322012-02-23 18:08:0611779 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811780 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2311781 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5211782 ASSERT_TRUE(ssl.cert);
[email protected]f45c1ee2010-08-03 00:54:3011783
[email protected]d973e99a2012-02-17 21:02:3611784 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511785 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11786 NULL, 0, NULL, 0);
11787 hanging_non_alternate_protocol_socket.set_connect_data(
11788 never_finishing_connect);
11789
[email protected]bb88e1d32013-05-03 23:11:0711790 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
11791 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
11792 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11793 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511794 &hanging_non_alternate_protocol_socket);
danakj1fd259a02016-04-16 03:17:0911795 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3011796
11797 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4111798 TestCompletionCallback callback_1;
danakj1fd259a02016-04-16 03:17:0911799 std::unique_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5011800 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111801 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011802 EXPECT_EQ(ERR_IO_PENDING, rv);
11803 EXPECT_EQ(OK, callback_1.WaitForResult());
11804
11805 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4111806 TestCompletionCallback callback_2;
danakj1fd259a02016-04-16 03:17:0911807 std::unique_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5011808 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111809 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011810 EXPECT_EQ(ERR_IO_PENDING, rv);
11811 EXPECT_EQ(OK, callback_2.WaitForResult());
11812 const HttpResponseInfo* response = trans_2->GetResponseInfo();
wezca1070932016-05-26 20:30:5211813 ASSERT_TRUE(response);
11814 ASSERT_TRUE(response->auth_challenge);
[email protected]f45c1ee2010-08-03 00:54:3011815
11816 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4111817 TestCompletionCallback callback_3;
11818 rv = trans_2->RestartWithAuth(
11819 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3011820 EXPECT_EQ(ERR_IO_PENDING, rv);
11821 EXPECT_EQ(OK, callback_3.WaitForResult());
11822
11823 // After all that work, these two lines (or actually, just the scheme) are
11824 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3011825 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2311826 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3011827
[email protected]029c83b62013-01-24 05:28:2011828 LoadTimingInfo load_timing_info;
11829 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
11830 TestLoadTimingNotReusedWithPac(load_timing_info,
11831 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3811832}
11833
11834// Test that if we cancel the transaction as the connection is completing, that
11835// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0211836TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3811837 // Setup everything about the connection to complete synchronously, so that
11838 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
11839 // for is the callback from the HttpStreamRequest.
11840 // Then cancel the transaction.
11841 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3611842 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3811843 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611844 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
11845 MockRead(SYNCHRONOUS, "hello world"),
11846 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3811847 };
11848
[email protected]8e6441ca2010-08-19 05:56:3811849 HttpRequestInfo request;
11850 request.method = "GET";
bncce36dca22015-04-21 22:11:2311851 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3811852 request.load_flags = 0;
11853
[email protected]bb88e1d32013-05-03 23:11:0711854 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0911855 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11856 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111857 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2711858
[email protected]8e6441ca2010-08-19 05:56:3811859 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11860 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711861 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3811862
[email protected]49639fa2011-12-20 23:22:4111863 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3811864
vishal.b62985ca92015-04-17 08:45:5111865 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4111866 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3811867 EXPECT_EQ(ERR_IO_PENDING, rv);
11868 trans.reset(); // Cancel the transaction here.
11869
[email protected]2da659e2013-05-23 20:51:3411870 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3011871}
11872
[email protected]ecab6e052014-05-16 14:58:1211873// Test that if a transaction is cancelled after receiving the headers, the
11874// stream is drained properly and added back to the socket pool. The main
11875// purpose of this test is to make sure that an HttpStreamParser can be read
11876// from after the HttpNetworkTransaction and the objects it owns have been
11877// deleted.
11878// See http://crbug.com/368418
11879TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
11880 MockRead data_reads[] = {
11881 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
11882 MockRead(ASYNC, "Content-Length: 2\r\n"),
11883 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
11884 MockRead(ASYNC, "1"),
11885 // 2 async reads are necessary to trigger a ReadResponseBody call after the
11886 // HttpNetworkTransaction has been deleted.
11887 MockRead(ASYNC, "2"),
11888 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
11889 };
11890 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11891 session_deps_.socket_factory->AddSocketDataProvider(&data);
11892
danakj1fd259a02016-04-16 03:17:0911893 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1211894
11895 {
11896 HttpRequestInfo request;
11897 request.method = "GET";
bncce36dca22015-04-21 22:11:2311898 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1211899 request.load_flags = 0;
11900
dcheng48459ac22014-08-26 00:46:4111901 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1211902 TestCompletionCallback callback;
11903
11904 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
11905 EXPECT_EQ(ERR_IO_PENDING, rv);
11906 callback.WaitForResult();
11907
11908 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211909 ASSERT_TRUE(response);
11910 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1211911 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11912
11913 // The transaction and HttpRequestInfo are deleted.
11914 }
11915
11916 // Let the HttpResponseBodyDrainer drain the socket.
11917 base::MessageLoop::current()->RunUntilIdle();
11918
11919 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4111920 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1211921}
11922
[email protected]76a505b2010-08-25 06:23:0011923// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211924TEST_P(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0311925 session_deps_.proxy_service =
11926 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111927 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711928 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0911929 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011930
[email protected]76a505b2010-08-25 06:23:0011931 HttpRequestInfo request;
11932 request.method = "GET";
bncce36dca22015-04-21 22:11:2311933 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011934
11935 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311936 MockWrite(
11937 "GET http://www.example.org/ HTTP/1.1\r\n"
11938 "Host: www.example.org\r\n"
11939 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011940 };
11941
11942 MockRead data_reads1[] = {
11943 MockRead("HTTP/1.1 200 OK\r\n"),
11944 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11945 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611946 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011947 };
11948
11949 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11950 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711951 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0011952
[email protected]49639fa2011-12-20 23:22:4111953 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011954
danakj1fd259a02016-04-16 03:17:0911955 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011956 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2711957 BeforeProxyHeadersSentHandler proxy_headers_handler;
11958 trans->SetBeforeProxyHeadersSentCallback(
11959 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
11960 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5011961
[email protected]49639fa2011-12-20 23:22:4111962 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011963 EXPECT_EQ(ERR_IO_PENDING, rv);
11964
11965 rv = callback1.WaitForResult();
11966 EXPECT_EQ(OK, rv);
11967
11968 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211969 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0011970
11971 EXPECT_TRUE(response->headers->IsKeepAlive());
11972 EXPECT_EQ(200, response->headers->response_code());
11973 EXPECT_EQ(100, response->headers->GetContentLength());
11974 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511975 EXPECT_TRUE(
11976 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2711977 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
11978 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0011979 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2011980
11981 LoadTimingInfo load_timing_info;
11982 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11983 TestLoadTimingNotReusedWithPac(load_timing_info,
11984 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0011985}
11986
11987// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211988TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0311989 session_deps_.proxy_service =
11990 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111991 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711992 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0911993 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011994
[email protected]76a505b2010-08-25 06:23:0011995 HttpRequestInfo request;
11996 request.method = "GET";
bncce36dca22015-04-21 22:11:2311997 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011998
11999 // Since we have proxy, should try to establish tunnel.
12000 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712001 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12002 "Host: www.example.org:443\r\n"
12003 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012004
rsleevidb16bb02015-11-12 23:47:1712005 MockWrite("GET / HTTP/1.1\r\n"
12006 "Host: www.example.org\r\n"
12007 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012008 };
12009
12010 MockRead data_reads1[] = {
12011 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12012
12013 MockRead("HTTP/1.1 200 OK\r\n"),
12014 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12015 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612016 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012017 };
12018
12019 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12020 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712021 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612022 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712023 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012024
[email protected]49639fa2011-12-20 23:22:4112025 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012026
danakj1fd259a02016-04-16 03:17:0912027 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012028 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5012029
[email protected]49639fa2011-12-20 23:22:4112030 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012031 EXPECT_EQ(ERR_IO_PENDING, rv);
12032
12033 rv = callback1.WaitForResult();
12034 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4612035 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012036 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012037 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012038 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012039 NetLog::PHASE_NONE);
12040 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012041 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012042 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12043 NetLog::PHASE_NONE);
12044
12045 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212046 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012047
12048 EXPECT_TRUE(response->headers->IsKeepAlive());
12049 EXPECT_EQ(200, response->headers->response_code());
12050 EXPECT_EQ(100, response->headers->GetContentLength());
12051 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12052 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512053 EXPECT_TRUE(
12054 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2012055
12056 LoadTimingInfo load_timing_info;
12057 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12058 TestLoadTimingNotReusedWithPac(load_timing_info,
12059 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012060}
12061
rsleevidb16bb02015-11-12 23:47:1712062// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12063// literal host.
12064TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
12065 session_deps_.proxy_service =
12066 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12067 BoundTestNetLog log;
12068 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712070
12071 HttpRequestInfo request;
12072 request.method = "GET";
12073 request.url = GURL("https://[::1]:443/");
12074
12075 // Since we have proxy, should try to establish tunnel.
12076 MockWrite data_writes1[] = {
12077 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12078 "Host: [::1]:443\r\n"
12079 "Proxy-Connection: keep-alive\r\n\r\n"),
12080
12081 MockWrite("GET / HTTP/1.1\r\n"
12082 "Host: [::1]\r\n"
12083 "Connection: keep-alive\r\n\r\n"),
12084 };
12085
12086 MockRead data_reads1[] = {
12087 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12088
12089 MockRead("HTTP/1.1 200 OK\r\n"),
12090 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12091 MockRead("Content-Length: 100\r\n\r\n"),
12092 MockRead(SYNCHRONOUS, OK),
12093 };
12094
12095 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12096 data_writes1, arraysize(data_writes1));
12097 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12098 SSLSocketDataProvider ssl(ASYNC, OK);
12099 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12100
12101 TestCompletionCallback callback1;
12102
danakj1fd259a02016-04-16 03:17:0912103 std::unique_ptr<HttpTransaction> trans(
rsleevidb16bb02015-11-12 23:47:1712104 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12105
12106 int rv = trans->Start(&request, callback1.callback(), log.bound());
12107 EXPECT_EQ(ERR_IO_PENDING, rv);
12108
12109 rv = callback1.WaitForResult();
12110 EXPECT_EQ(OK, rv);
12111 TestNetLogEntry::List entries;
12112 log.GetEntries(&entries);
12113 size_t pos = ExpectLogContainsSomewhere(
12114 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12115 NetLog::PHASE_NONE);
12116 ExpectLogContainsSomewhere(
12117 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12118 NetLog::PHASE_NONE);
12119
12120 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212121 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712122
12123 EXPECT_TRUE(response->headers->IsKeepAlive());
12124 EXPECT_EQ(200, response->headers->response_code());
12125 EXPECT_EQ(100, response->headers->GetContentLength());
12126 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12127 EXPECT_TRUE(response->was_fetched_via_proxy);
12128 EXPECT_TRUE(
12129 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
12130
12131 LoadTimingInfo load_timing_info;
12132 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12133 TestLoadTimingNotReusedWithPac(load_timing_info,
12134 CONNECT_TIMING_HAS_SSL_TIMES);
12135}
12136
[email protected]76a505b2010-08-25 06:23:0012137// Test a basic HTTPS GET request through a proxy, but the server hangs up
12138// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0212139TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312140 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112141 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712142 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912143 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012144
[email protected]76a505b2010-08-25 06:23:0012145 HttpRequestInfo request;
12146 request.method = "GET";
bncce36dca22015-04-21 22:11:2312147 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012148
12149 // Since we have proxy, should try to establish tunnel.
12150 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712151 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12152 "Host: www.example.org:443\r\n"
12153 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012154
rsleevidb16bb02015-11-12 23:47:1712155 MockWrite("GET / HTTP/1.1\r\n"
12156 "Host: www.example.org\r\n"
12157 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012158 };
12159
12160 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0612161 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0012162 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612163 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0012164 };
12165
12166 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12167 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712168 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612169 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712170 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012171
[email protected]49639fa2011-12-20 23:22:4112172 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012173
danakj1fd259a02016-04-16 03:17:0912174 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012175 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5012176
[email protected]49639fa2011-12-20 23:22:4112177 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012178 EXPECT_EQ(ERR_IO_PENDING, rv);
12179
12180 rv = callback1.WaitForResult();
12181 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4612182 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012183 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012184 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012185 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012186 NetLog::PHASE_NONE);
12187 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012188 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012189 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12190 NetLog::PHASE_NONE);
12191}
12192
[email protected]749eefa82010-09-13 22:14:0312193// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0212194TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
danakj1fd259a02016-04-16 03:17:0912195 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912196 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1312197 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0312198
danakj1fd259a02016-04-16 03:17:0912199 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5512200 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912201 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5512202 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0312203 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312204 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0312205 };
12206
rch8e6c6c42015-05-01 14:05:1312207 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12208 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712209 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0312210
[email protected]8ddf8322012-02-23 18:08:0612211 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812212 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712213 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0312214
danakj1fd259a02016-04-16 03:17:0912215 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0312216
12217 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2312218 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012219 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312220 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712221 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4212222 CreateInsecureSpdySession(session.get(), key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312223
12224 HttpRequestInfo request;
12225 request.method = "GET";
bncce36dca22015-04-21 22:11:2312226 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0312227 request.load_flags = 0;
12228
12229 // This is the important line that marks this as a preconnect.
12230 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
12231
danakj1fd259a02016-04-16 03:17:0912232 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012233 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0312234
[email protected]41d64e82013-07-03 22:44:2612235 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4112236 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312237 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112238 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0312239}
12240
[email protected]73b8dd222010-11-11 19:55:2412241// Given a net error, cause that error to be returned from the first Write()
12242// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0212243void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0712244 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2912245 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712246 request_info.url = GURL("https://www.example.com/");
12247 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912248 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712249
[email protected]8ddf8322012-02-23 18:08:0612250 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2912251 MockWrite data_writes[] = {
12252 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2412253 };
ttuttle859dc7a2015-04-23 19:42:2912254 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712255 session_deps_.socket_factory->AddSocketDataProvider(&data);
12256 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2412257
danakj1fd259a02016-04-16 03:17:0912258 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12259 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012260 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2412261
[email protected]49639fa2011-12-20 23:22:4112262 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912263 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12264 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2412265 rv = callback.WaitForResult();
12266 ASSERT_EQ(error, rv);
12267}
12268
[email protected]23e482282013-06-14 16:08:0212269TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2412270 // Just check a grab bag of cert errors.
12271 static const int kErrors[] = {
12272 ERR_CERT_COMMON_NAME_INVALID,
12273 ERR_CERT_AUTHORITY_INVALID,
12274 ERR_CERT_DATE_INVALID,
12275 };
12276 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0612277 CheckErrorIsPassedBack(kErrors[i], ASYNC);
12278 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2412279 }
12280}
12281
[email protected]bd0b6772011-01-11 19:59:3012282// Ensure that a client certificate is removed from the SSL client auth
12283// cache when:
12284// 1) No proxy is involved.
12285// 2) TLS False Start is disabled.
12286// 3) The initial TLS handshake requests a client certificate.
12287// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212288TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312289 ClientAuthCertCache_Direct_NoFalseStart) {
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]bd0b6772011-01-11 19:59:3012295 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112296 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012297
12298 // [ssl_]data1 contains the data for the first SSL handshake. When a
12299 // CertificateRequest is received for the first time, the handshake will
12300 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2912301 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012302 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712303 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912304 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712305 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012306
12307 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
12308 // False Start is not being used, the result of the SSL handshake will be
12309 // returned as part of the SSLClientSocket::Connect() call. This test
12310 // matches the result of a server sending a handshake_failure alert,
12311 // rather than a Finished message, because it requires a client
12312 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2912313 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012314 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712315 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912316 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712317 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012318
12319 // [ssl_]data3 contains the data for the third SSL handshake. When a
12320 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212321 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
12322 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3012323 // of the HttpNetworkTransaction. Because this test failure is due to
12324 // requiring a client certificate, this fallback handshake should also
12325 // fail.
ttuttle859dc7a2015-04-23 19:42:2912326 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012327 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712328 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912329 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712330 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012331
[email protected]80c75f682012-05-26 16:22:1712332 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
12333 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212334 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
12335 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1712336 // of the HttpNetworkTransaction. Because this test failure is due to
12337 // requiring a client certificate, this fallback handshake should also
12338 // fail.
ttuttle859dc7a2015-04-23 19:42:2912339 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1712340 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712341 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912342 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712343 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712344
danakj1fd259a02016-04-16 03:17:0912345 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12346 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012347 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012348
[email protected]bd0b6772011-01-11 19:59:3012349 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4112350 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912351 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12352 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012353
12354 // Complete the SSL handshake, which should abort due to requiring a
12355 // client certificate.
12356 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912357 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012358
12359 // Indicate that no certificate should be supplied. From the perspective
12360 // of SSLClientCertCache, NULL is just as meaningful as a real
12361 // certificate, so this is the same as supply a
12362 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412363 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912364 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012365
12366 // Ensure the certificate was added to the client auth cache before
12367 // allowing the connection to continue restarting.
12368 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412369 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112370 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412371 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212372 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012373
12374 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712375 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12376 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012377 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912378 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012379
12380 // Ensure that the client certificate is removed from the cache on a
12381 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112382 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412383 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012384}
12385
12386// Ensure that a client certificate is removed from the SSL client auth
12387// cache when:
12388// 1) No proxy is involved.
12389// 2) TLS False Start is enabled.
12390// 3) The initial TLS handshake requests a client certificate.
12391// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212392TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312393 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912394 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712395 request_info.url = GURL("https://www.example.com/");
12396 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912397 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712398
[email protected]bd0b6772011-01-11 19:59:3012399 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112400 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012401
12402 // When TLS False Start is used, SSLClientSocket::Connect() calls will
12403 // return successfully after reading up to the peer's Certificate message.
12404 // This is to allow the caller to call SSLClientSocket::Write(), which can
12405 // enqueue application data to be sent in the same packet as the
12406 // ChangeCipherSpec and Finished messages.
12407 // The actual handshake will be finished when SSLClientSocket::Read() is
12408 // called, which expects to process the peer's ChangeCipherSpec and
12409 // Finished messages. If there was an error negotiating with the peer,
12410 // such as due to the peer requiring a client certificate when none was
12411 // supplied, the alert sent by the peer won't be processed until Read() is
12412 // called.
12413
12414 // Like the non-False Start case, when a client certificate is requested by
12415 // the peer, the handshake is aborted during the Connect() call.
12416 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2912417 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012418 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712419 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912420 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712421 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012422
12423 // When a client certificate is supplied, Connect() will not be aborted
12424 // when the peer requests the certificate. Instead, the handshake will
12425 // artificially succeed, allowing the caller to write the HTTP request to
12426 // the socket. The handshake messages are not processed until Read() is
12427 // called, which then detects that the handshake was aborted, due to the
12428 // peer sending a handshake_failure because it requires a client
12429 // certificate.
ttuttle859dc7a2015-04-23 19:42:2912430 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012431 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712432 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912433 MockRead data2_reads[] = {
12434 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3012435 };
ttuttle859dc7a2015-04-23 19:42:2912436 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712437 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012438
12439 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1712440 // the data for the SSL handshake once the TLSv1.1 connection falls back to
12441 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912442 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012443 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712444 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912445 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712446 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012447
[email protected]80c75f682012-05-26 16:22:1712448 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
12449 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912450 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1712451 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712452 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912453 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712454 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712455
[email protected]7799de12013-05-30 05:52:5112456 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2912457 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5112458 ssl_data5.cert_request_info = cert_request.get();
12459 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2912460 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5112461 session_deps_.socket_factory->AddSocketDataProvider(&data5);
12462
danakj1fd259a02016-04-16 03:17:0912463 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12464 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012465 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012466
[email protected]bd0b6772011-01-11 19:59:3012467 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4112468 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912469 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12470 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012471
12472 // Complete the SSL handshake, which should abort due to requiring a
12473 // client certificate.
12474 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912475 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012476
12477 // Indicate that no certificate should be supplied. From the perspective
12478 // of SSLClientCertCache, NULL is just as meaningful as a real
12479 // certificate, so this is the same as supply a
12480 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412481 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912482 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012483
12484 // Ensure the certificate was added to the client auth cache before
12485 // allowing the connection to continue restarting.
12486 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412487 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112488 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412489 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212490 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012491
[email protected]bd0b6772011-01-11 19:59:3012492 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712493 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12494 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012495 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912496 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012497
12498 // Ensure that the client certificate is removed from the cache on a
12499 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112500 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412501 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012502}
12503
[email protected]8c405132011-01-11 22:03:1812504// Ensure that a client certificate is removed from the SSL client auth
12505// cache when:
12506// 1) An HTTPS proxy is involved.
12507// 3) The HTTPS proxy requests a client certificate.
12508// 4) The client supplies an invalid/unacceptable certificate for the
12509// proxy.
12510// The test is repeated twice, first for connecting to an HTTPS endpoint,
12511// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0212512TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0312513 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5112514 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712515 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1812516
12517 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112518 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1812519
12520 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
12521 // [ssl_]data[1-3]. Rather than represending the endpoint
12522 // (www.example.com:443), they represent failures with the HTTPS proxy
12523 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2912524 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1812525 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712526 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912527 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712528 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1812529
ttuttle859dc7a2015-04-23 19:42:2912530 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812531 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712532 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912533 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712534 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1812535
[email protected]80c75f682012-05-26 16:22:1712536 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
12537#if 0
ttuttle859dc7a2015-04-23 19:42:2912538 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812539 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712540 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912541 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712542 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1712543#endif
[email protected]8c405132011-01-11 22:03:1812544
ttuttle859dc7a2015-04-23 19:42:2912545 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1812546 requests[0].url = GURL("https://www.example.com/");
12547 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912548 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812549
12550 requests[1].url = GURL("http://www.example.com/");
12551 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912552 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812553
12554 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0712555 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0912556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12557 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012558 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1812559
12560 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4112561 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912562 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
12563 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812564
12565 // Complete the SSL handshake, which should abort due to requiring a
12566 // client certificate.
12567 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912568 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1812569
12570 // Indicate that no certificate should be supplied. From the perspective
12571 // of SSLClientCertCache, NULL is just as meaningful as a real
12572 // certificate, so this is the same as supply a
12573 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412574 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912575 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812576
12577 // Ensure the certificate was added to the client auth cache before
12578 // allowing the connection to continue restarting.
12579 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412580 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112581 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412582 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212583 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1812584 // Ensure the certificate was NOT cached for the endpoint. This only
12585 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4112586 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412587 HostPortPair("www.example.com", 443), &client_cert,
12588 &client_private_key));
[email protected]8c405132011-01-11 22:03:1812589
12590 // Restart the handshake. This will consume ssl_data2, which fails, and
12591 // then consume ssl_data3, which should also fail. The result code is
12592 // checked against what ssl_data3 should return.
12593 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912594 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1812595
12596 // Now that the new handshake has failed, ensure that the client
12597 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4112598 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412599 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4112600 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412601 HostPortPair("www.example.com", 443), &client_cert,
12602 &client_private_key));
[email protected]8c405132011-01-11 22:03:1812603 }
12604}
12605
mmenke5c642132015-06-02 16:05:1312606TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bncf33fb31b2016-01-29 15:22:2612607 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4612608
12609 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712610 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0912611 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612612 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12613 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612614
[email protected]8ddf8322012-02-23 18:08:0612615 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812616 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712617 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612618
danakj1fd259a02016-04-16 03:17:0912619 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4912620 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812621 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0912622 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4912623 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612624 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312625 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612626 };
danakj1fd259a02016-04-16 03:17:0912627 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0212628 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912629 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0212630 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0912631 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0212632 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0912633 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0212634 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612635 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312636 CreateMockRead(*host1_resp, 1),
12637 CreateMockRead(*host1_resp_body, 2),
12638 CreateMockRead(*host2_resp, 4),
12639 CreateMockRead(*host2_resp_body, 5),
12640 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612641 };
12642
eroman36d84e54432016-03-17 03:23:0212643 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0212644 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312645 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12646 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712647 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612648
[email protected]aa22b242011-11-16 18:58:2912649 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612650 HttpRequestInfo request1;
12651 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312652 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612653 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012654 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612655
[email protected]49639fa2011-12-20 23:22:4112656 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612657 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112658 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612659
12660 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212661 ASSERT_TRUE(response);
12662 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212663 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612664
12665 std::string response_data;
12666 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12667 EXPECT_EQ("hello!", response_data);
12668
12669 // Preload www.gmail.com into HostCache.
12670 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1012671 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4612672 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012673 rv = session_deps_.host_resolver->Resolve(resolve_info,
12674 DEFAULT_PRIORITY,
12675 &ignored,
12676 callback.callback(),
12677 NULL,
12678 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712679 EXPECT_EQ(ERR_IO_PENDING, rv);
12680 rv = callback.WaitForResult();
12681 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612682
12683 HttpRequestInfo request2;
12684 request2.method = "GET";
12685 request2.url = GURL("https://www.gmail.com/");
12686 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012687 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612688
[email protected]49639fa2011-12-20 23:22:4112689 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612690 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112691 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612692
12693 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212694 ASSERT_TRUE(response);
12695 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212696 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612697 EXPECT_TRUE(response->was_fetched_via_spdy);
12698 EXPECT_TRUE(response->was_npn_negotiated);
12699 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12700 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612701}
12702
[email protected]23e482282013-06-14 16:08:0212703TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bncf33fb31b2016-01-29 15:22:2612704 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d2b5f092012-06-08 23:55:0212705
12706 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712707 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0912708 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0212709 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12710 pool_peer.DisableDomainAuthenticationVerification();
12711
12712 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812713 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712714 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0212715
danakj1fd259a02016-04-16 03:17:0912716 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4912717 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812718 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0912719 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4912720 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0212721 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312722 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0212723 };
danakj1fd259a02016-04-16 03:17:0912724 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0212725 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912726 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0212727 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0912728 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0212729 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0912730 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0212731 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0212732 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312733 CreateMockRead(*host1_resp, 1),
12734 CreateMockRead(*host1_resp_body, 2),
12735 CreateMockRead(*host2_resp, 4),
12736 CreateMockRead(*host2_resp_body, 5),
12737 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0212738 };
12739
eroman36d84e54432016-03-17 03:23:0212740 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0212741 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312742 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12743 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712744 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0212745
12746 TestCompletionCallback callback;
12747 HttpRequestInfo request1;
12748 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312749 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0212750 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012751 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212752
12753 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
12754 EXPECT_EQ(ERR_IO_PENDING, rv);
12755 EXPECT_EQ(OK, callback.WaitForResult());
12756
12757 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212758 ASSERT_TRUE(response);
12759 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212760 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0212761
12762 std::string response_data;
12763 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12764 EXPECT_EQ("hello!", response_data);
12765
12766 HttpRequestInfo request2;
12767 request2.method = "GET";
12768 request2.url = GURL("https://www.gmail.com/");
12769 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012770 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0212771
12772 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
12773 EXPECT_EQ(ERR_IO_PENDING, rv);
12774 EXPECT_EQ(OK, callback.WaitForResult());
12775
12776 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212777 ASSERT_TRUE(response);
12778 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212779 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0212780 EXPECT_TRUE(response->was_fetched_via_spdy);
12781 EXPECT_TRUE(response->was_npn_negotiated);
12782 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12783 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0212784}
12785
ttuttle859dc7a2015-04-23 19:42:2912786class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4612787 public:
12788 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
12789 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2012790 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4612791
12792 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
12793
12794 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2012795 int Resolve(const RequestInfo& info,
12796 RequestPriority priority,
12797 AddressList* addresses,
12798 const CompletionCallback& callback,
12799 RequestHandle* out_req,
12800 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012801 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1012802 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4012803 }
12804
dchengb03027d2014-10-21 12:00:2012805 int ResolveFromCache(const RequestInfo& info,
12806 AddressList* addresses,
12807 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4012808 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
12809 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0912810 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4612811 return rv;
12812 }
12813
dchengb03027d2014-10-21 12:00:2012814 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4612815 host_resolver_.CancelRequest(req);
12816 }
12817
[email protected]46da33be2011-07-19 21:58:0412818 MockCachingHostResolver* GetMockHostResolver() {
12819 return &host_resolver_;
12820 }
12821
[email protected]e3ceb682011-06-28 23:55:4612822 private:
12823 MockCachingHostResolver host_resolver_;
12824 const HostPortPair host_port_;
12825};
12826
mmenke5c642132015-06-02 16:05:1312827TEST_P(HttpNetworkTransactionTest,
12828 UseIPConnectionPoolingWithHostCacheExpiration) {
bncf33fb31b2016-01-29 15:22:2612829 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4612830
12831 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4612832 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3412833 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0712834 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4612835 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0912836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612837 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12838 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612839
[email protected]8ddf8322012-02-23 18:08:0612840 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812841 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712842 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612843
danakj1fd259a02016-04-16 03:17:0912844 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4912845 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812846 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0912847 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4912848 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612849 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312850 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612851 };
danakj1fd259a02016-04-16 03:17:0912852 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0212853 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912854 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0212855 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0912856 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0212857 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0912858 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0212859 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612860 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312861 CreateMockRead(*host1_resp, 1),
12862 CreateMockRead(*host1_resp_body, 2),
12863 CreateMockRead(*host2_resp, 4),
12864 CreateMockRead(*host2_resp_body, 5),
12865 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612866 };
12867
eroman36d84e54432016-03-17 03:23:0212868 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0212869 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312870 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12871 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712872 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612873
[email protected]aa22b242011-11-16 18:58:2912874 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612875 HttpRequestInfo request1;
12876 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312877 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612878 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012879 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612880
[email protected]49639fa2011-12-20 23:22:4112881 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612882 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112883 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612884
12885 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212886 ASSERT_TRUE(response);
12887 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212888 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612889
12890 std::string response_data;
12891 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12892 EXPECT_EQ("hello!", response_data);
12893
12894 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1012895 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4612896 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012897 rv = host_resolver.Resolve(resolve_info,
12898 DEFAULT_PRIORITY,
12899 &ignored,
12900 callback.callback(),
12901 NULL,
12902 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712903 EXPECT_EQ(ERR_IO_PENDING, rv);
12904 rv = callback.WaitForResult();
12905 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612906
12907 HttpRequestInfo request2;
12908 request2.method = "GET";
12909 request2.url = GURL("https://www.gmail.com/");
12910 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012911 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612912
[email protected]49639fa2011-12-20 23:22:4112913 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612914 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112915 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612916
12917 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212918 ASSERT_TRUE(response);
12919 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212920 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612921 EXPECT_TRUE(response->was_fetched_via_spdy);
12922 EXPECT_TRUE(response->was_npn_negotiated);
12923 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12924 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612925}
12926
[email protected]23e482282013-06-14 16:08:0212927TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2312928 const std::string https_url = "https://www.example.org:8080/";
12929 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412930
12931 // SPDY GET for HTTPS URL
danakj1fd259a02016-04-16 03:17:0912932 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4912933 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0412934
12935 MockWrite writes1[] = {
12936 CreateMockWrite(*req1, 0),
12937 };
12938
danakj1fd259a02016-04-16 03:17:0912939 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5512940 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912941 std::unique_ptr<SpdySerializedFrame> body1(
bncb03b1092016-04-06 11:19:5512942 spdy_util_.ConstructSpdyBodyFrame(1, true));
mmenkee24011922015-12-17 22:12:5912943 MockRead reads1[] = {CreateMockRead(*resp1, 1), CreateMockRead(*body1, 2),
12944 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0412945
rch8e6c6c42015-05-01 14:05:1312946 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
12947 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412948 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712949 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412950
12951 // HTTP GET for the HTTP URL
12952 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1312953 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3412954 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2312955 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3412956 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0412957 };
12958
12959 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1312960 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12961 MockRead(ASYNC, 2, "hello"),
12962 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0412963 };
12964
rch8e6c6c42015-05-01 14:05:1312965 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12966 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0412967
[email protected]8450d722012-07-02 19:14:0412968 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812969 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712970 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12971 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12972 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0412973
danakj1fd259a02016-04-16 03:17:0912974 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412975
12976 // Start the first transaction to set up the SpdySession
12977 HttpRequestInfo request1;
12978 request1.method = "GET";
12979 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412980 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012981 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412982 TestCompletionCallback callback1;
12983 EXPECT_EQ(ERR_IO_PENDING,
12984 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412985 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412986
12987 EXPECT_EQ(OK, callback1.WaitForResult());
12988 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12989
12990 // Now, start the HTTP request
12991 HttpRequestInfo request2;
12992 request2.method = "GET";
12993 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412994 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012995 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412996 TestCompletionCallback callback2;
12997 EXPECT_EQ(ERR_IO_PENDING,
12998 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412999 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413000
13001 EXPECT_EQ(OK, callback2.WaitForResult());
13002 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13003}
13004
bnc1b0e36852015-04-28 15:32:5913005class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
13006 public:
13007 void Run(bool pooling, bool valid) {
zhongyi3d4a55e72016-04-22 20:36:4613008 url::SchemeHostPort server(GURL(valid ? "https://mail.example.org:443"
13009 : "https://invalid.example.org:443"));
bnc1b0e36852015-04-28 15:32:5913010 HostPortPair alternative("www.example.org", 443);
13011
13012 base::FilePath certs_dir = GetTestCertsDirectory();
13013 scoped_refptr<X509Certificate> cert(
13014 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
wezca1070932016-05-26 20:30:5213015 ASSERT_TRUE(cert);
bnc1b0e36852015-04-28 15:32:5913016 bool common_name_fallback_used;
13017 EXPECT_EQ(valid,
zhongyi3d4a55e72016-04-22 20:36:4613018 cert->VerifyNameMatch(server.host(), &common_name_fallback_used));
bnc1b0e36852015-04-28 15:32:5913019 EXPECT_TRUE(
13020 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
13021 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813022 ssl.SetNextProto(GetProtocol());
bnc1b0e36852015-04-28 15:32:5913023 ssl.cert = cert;
13024 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13025
13026 // If pooling, then start a request to alternative first to create a
13027 // SpdySession.
13028 std::string url0 = "https://www.example.org:443";
zhongyi3d4a55e72016-04-22 20:36:4613029 // Second request to server, which has an alternative service, and could
bnc1b0e36852015-04-28 15:32:5913030 // open a connection to the alternative host or pool to the existing one.
13031 std::string url1("https://");
zhongyi3d4a55e72016-04-22 20:36:4613032 url1.append(server.host());
bnc1b0e36852015-04-28 15:32:5913033 url1.append(":443");
13034
danakj1fd259a02016-04-16 03:17:0913035 std::unique_ptr<SpdySerializedFrame> req0;
13036 std::unique_ptr<SpdySerializedFrame> req1;
13037 std::unique_ptr<SpdySerializedFrame> resp0;
13038 std::unique_ptr<SpdySerializedFrame> body0;
13039 std::unique_ptr<SpdySerializedFrame> resp1;
13040 std::unique_ptr<SpdySerializedFrame> body1;
bnc1b0e36852015-04-28 15:32:5913041 std::vector<MockWrite> writes;
13042 std::vector<MockRead> reads;
13043
13044 if (pooling) {
bnc38dcd392016-02-09 23:19:4913045 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813046 spdy_util_.UpdateWithStreamDestruction(1);
bnc38dcd392016-02-09 23:19:4913047 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 3, LOWEST));
bnc1b0e36852015-04-28 15:32:5913048
13049 writes.push_back(CreateMockWrite(*req0, 0));
13050 writes.push_back(CreateMockWrite(*req1, 3));
13051
13052 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13053 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13054 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
13055 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
13056
13057 reads.push_back(CreateMockRead(*resp0, 1));
13058 reads.push_back(CreateMockRead(*body0, 2));
13059 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
13060 reads.push_back(CreateMockRead(*resp1, 5));
13061 reads.push_back(CreateMockRead(*body1, 6));
13062 reads.push_back(MockRead(ASYNC, OK, 7));
13063 } else {
bnc38dcd392016-02-09 23:19:4913064 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 1, LOWEST));
bnc1b0e36852015-04-28 15:32:5913065
13066 writes.push_back(CreateMockWrite(*req1, 0));
13067
13068 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13069 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13070
13071 reads.push_back(CreateMockRead(*resp1, 1));
13072 reads.push_back(CreateMockRead(*body1, 2));
13073 reads.push_back(MockRead(ASYNC, OK, 3));
13074 }
13075
davidben5f8b6bc2015-11-25 03:19:5413076 SequencedSocketData data(reads.data(), reads.size(), writes.data(),
13077 writes.size());
bnc1b0e36852015-04-28 15:32:5913078 session_deps_.socket_factory->AddSocketDataProvider(&data);
13079
zhongyi3d4a55e72016-04-22 20:36:4613080 // Connection to the server fails.
bnc1b0e36852015-04-28 15:32:5913081 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13082 StaticSocketDataProvider data_refused;
13083 data_refused.set_connect_data(mock_connect);
13084 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13085
bncf33fb31b2016-01-29 15:22:2613086 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc1b0e36852015-04-28 15:32:5913088 base::WeakPtr<HttpServerProperties> http_server_properties =
13089 session->http_server_properties();
13090 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813091 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213092 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613093 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013094 expiration);
bnc1b0e36852015-04-28 15:32:5913095
13096 // First request to alternative.
13097 if (pooling) {
danakj1fd259a02016-04-16 03:17:0913098 std::unique_ptr<HttpTransaction> trans0(
bnc1b0e36852015-04-28 15:32:5913099 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13100 HttpRequestInfo request0;
13101 request0.method = "GET";
13102 request0.url = GURL(url0);
13103 request0.load_flags = 0;
13104 TestCompletionCallback callback0;
13105
13106 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
13107 EXPECT_EQ(ERR_IO_PENDING, rv);
13108 rv = callback0.WaitForResult();
13109 EXPECT_EQ(OK, rv);
13110 }
13111
13112 // Second request to origin.
danakj1fd259a02016-04-16 03:17:0913113 std::unique_ptr<HttpTransaction> trans1(
bnc1b0e36852015-04-28 15:32:5913114 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13115 HttpRequestInfo request1;
13116 request1.method = "GET";
13117 request1.url = GURL(url1);
13118 request1.load_flags = 0;
13119 TestCompletionCallback callback1;
13120
13121 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13122 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0913123 base::MessageLoop::current()->RunUntilIdle();
mmenkee24011922015-12-17 22:12:5913124 if (data.IsPaused())
13125 data.Resume();
bnc1b0e36852015-04-28 15:32:5913126 rv = callback1.WaitForResult();
13127 if (valid) {
13128 EXPECT_EQ(OK, rv);
13129 } else {
13130 if (pooling) {
13131 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13132 } else {
13133 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
13134 }
13135 }
13136 }
13137};
13138
rdsmithebb50aa2015-11-12 03:44:3813139INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc1b0e36852015-04-28 15:32:5913140 AltSvcCertificateVerificationTest,
rdsmithebb50aa2015-11-12 03:44:3813141 testing::Values(kTestCaseSPDY31,
13142 kTestCaseHTTP2NoPriorityDependencies,
13143 kTestCaseHTTP2PriorityDependencies));
bnc1b0e36852015-04-28 15:32:5913144
13145// The alternative service host must exhibit a certificate that is valid for the
13146// origin host. Test that this is enforced when pooling to an existing
13147// connection.
13148TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
13149 Run(true, true);
13150}
13151
13152TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
13153 Run(true, false);
13154}
13155
13156// The alternative service host must exhibit a certificate that is valid for the
13157// origin host. Test that this is enforced when opening a new connection.
13158TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
13159 Run(false, true);
13160}
13161
13162TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
13163 Run(false, false);
13164}
13165
bnc5452e2a2015-05-08 16:27:4213166// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13167// with the alternative server. That connection should not be used.
13168TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4613169 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4213170 HostPortPair alternative("alternative.example.org", 443);
13171
13172 // Negotiate HTTP/1.1 with alternative.example.org.
13173 SSLSocketDataProvider ssl(ASYNC, OK);
13174 ssl.SetNextProto(kProtoHTTP11);
13175 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13176
13177 // No data should be read from the alternative, because HTTP/1.1 is
13178 // negotiated.
13179 StaticSocketDataProvider data;
13180 session_deps_.socket_factory->AddSocketDataProvider(&data);
13181
13182 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4613183 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4213184 // mocked. This way the request relies on the alternate Job.
13185 StaticSocketDataProvider data_refused;
13186 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13187 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13188
zhongyi3d4a55e72016-04-22 20:36:4613189 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613190 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913191 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213192 base::WeakPtr<HttpServerProperties> http_server_properties =
13193 session->http_server_properties();
13194 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813195 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213196 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613197 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013198 expiration);
bnc5452e2a2015-05-08 16:27:4213199
danakj1fd259a02016-04-16 03:17:0913200 std::unique_ptr<HttpTransaction> trans(
bnc5452e2a2015-05-08 16:27:4213201 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13202 HttpRequestInfo request;
13203 request.method = "GET";
13204 request.url = GURL("https://origin.example.org:443");
13205 request.load_flags = 0;
13206 TestCompletionCallback callback;
13207
13208 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
13209 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
13210 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13211 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
13212}
13213
bnc40448a532015-05-11 19:13:1413214// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4613215// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1413216// succeeds, the request should succeed, even if the latter fails because
13217// HTTP/1.1 is negotiated which is insufficient for alternative service.
13218TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
zhongyi3d4a55e72016-04-22 20:36:4613219 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc40448a532015-05-11 19:13:1413220 HostPortPair alternative("alternative.example.org", 443);
13221
13222 // Negotiate HTTP/1.1 with alternative.
13223 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
13224 alternative_ssl.SetNextProto(kProtoHTTP11);
13225 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13226
13227 // No data should be read from the alternative, because HTTP/1.1 is
13228 // negotiated.
13229 StaticSocketDataProvider data;
13230 session_deps_.socket_factory->AddSocketDataProvider(&data);
13231
zhongyi3d4a55e72016-04-22 20:36:4613232 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1413233 SSLSocketDataProvider origin_ssl(ASYNC, OK);
13234 origin_ssl.SetNextProto(kProtoHTTP11);
13235 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13236
13237 MockWrite http_writes[] = {
13238 MockWrite(
13239 "GET / HTTP/1.1\r\n"
13240 "Host: origin.example.org\r\n"
13241 "Connection: keep-alive\r\n\r\n"),
13242 MockWrite(
13243 "GET /second HTTP/1.1\r\n"
13244 "Host: origin.example.org\r\n"
13245 "Connection: keep-alive\r\n\r\n"),
13246 };
13247
13248 MockRead http_reads[] = {
13249 MockRead("HTTP/1.1 200 OK\r\n"),
13250 MockRead("Content-Type: text/html\r\n"),
13251 MockRead("Content-Length: 6\r\n\r\n"),
13252 MockRead("foobar"),
13253 MockRead("HTTP/1.1 200 OK\r\n"),
13254 MockRead("Content-Type: text/html\r\n"),
13255 MockRead("Content-Length: 7\r\n\r\n"),
13256 MockRead("another"),
13257 };
13258 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13259 http_writes, arraysize(http_writes));
13260 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13261
zhongyi3d4a55e72016-04-22 20:36:4613262 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613263 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913264 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc40448a532015-05-11 19:13:1413265 base::WeakPtr<HttpServerProperties> http_server_properties =
13266 session->http_server_properties();
13267 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813268 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213269 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613270 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013271 expiration);
bnc40448a532015-05-11 19:13:1413272
13273 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13274 HttpRequestInfo request1;
13275 request1.method = "GET";
13276 request1.url = GURL("https://origin.example.org:443");
13277 request1.load_flags = 0;
13278 TestCompletionCallback callback1;
13279
13280 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
13281 rv = callback1.GetResult(rv);
13282 EXPECT_EQ(OK, rv);
13283
13284 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213285 ASSERT_TRUE(response1);
13286 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1413287 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13288
13289 std::string response_data1;
13290 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
13291 EXPECT_EQ("foobar", response_data1);
13292
13293 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13294 // for alternative service.
13295 EXPECT_TRUE(
13296 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13297
zhongyi3d4a55e72016-04-22 20:36:4613298 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1413299 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4613300 // to server.
bnc40448a532015-05-11 19:13:1413301 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13302 HttpRequestInfo request2;
13303 request2.method = "GET";
13304 request2.url = GURL("https://origin.example.org:443/second");
13305 request2.load_flags = 0;
13306 TestCompletionCallback callback2;
13307
13308 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
13309 rv = callback2.GetResult(rv);
13310 EXPECT_EQ(OK, rv);
13311
13312 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213313 ASSERT_TRUE(response2);
13314 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1413315 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13316
13317 std::string response_data2;
13318 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
13319 EXPECT_EQ("another", response_data2);
13320}
13321
bnc5452e2a2015-05-08 16:27:4213322// Alternative service requires HTTP/2 (or SPDY), but there is already a
13323// HTTP/1.1 socket open to the alternative server. That socket should not be
13324// used.
13325TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4613326 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4213327 HostPortPair alternative("alternative.example.org", 443);
13328 std::string origin_url = "https://origin.example.org:443";
13329 std::string alternative_url = "https://alternative.example.org:443";
13330
13331 // Negotiate HTTP/1.1 with alternative.example.org.
13332 SSLSocketDataProvider ssl(ASYNC, OK);
13333 ssl.SetNextProto(kProtoHTTP11);
13334 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13335
13336 // HTTP/1.1 data for |request1| and |request2|.
13337 MockWrite http_writes[] = {
13338 MockWrite(
13339 "GET / HTTP/1.1\r\n"
13340 "Host: alternative.example.org\r\n"
13341 "Connection: keep-alive\r\n\r\n"),
13342 MockWrite(
13343 "GET / HTTP/1.1\r\n"
13344 "Host: alternative.example.org\r\n"
13345 "Connection: keep-alive\r\n\r\n"),
13346 };
13347
13348 MockRead http_reads[] = {
13349 MockRead(
13350 "HTTP/1.1 200 OK\r\n"
13351 "Content-Type: text/html; charset=iso-8859-1\r\n"
13352 "Content-Length: 40\r\n\r\n"
13353 "first HTTP/1.1 response from alternative"),
13354 MockRead(
13355 "HTTP/1.1 200 OK\r\n"
13356 "Content-Type: text/html; charset=iso-8859-1\r\n"
13357 "Content-Length: 41\r\n\r\n"
13358 "second HTTP/1.1 response from alternative"),
13359 };
13360 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13361 http_writes, arraysize(http_writes));
13362 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13363
13364 // This test documents that an alternate Job should not pool to an already
13365 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4613366 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4213367 StaticSocketDataProvider data_refused;
13368 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13369 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13370
zhongyi3d4a55e72016-04-22 20:36:4613371 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613372 session_deps_.enable_alternative_service_with_different_host = false;
danakj1fd259a02016-04-16 03:17:0913373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213374 base::WeakPtr<HttpServerProperties> http_server_properties =
13375 session->http_server_properties();
13376 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813377 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213378 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613379 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013380 expiration);
bnc5452e2a2015-05-08 16:27:4213381
13382 // First transaction to alternative to open an HTTP/1.1 socket.
danakj1fd259a02016-04-16 03:17:0913383 std::unique_ptr<HttpTransaction> trans1(
bnc5452e2a2015-05-08 16:27:4213384 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13385 HttpRequestInfo request1;
13386 request1.method = "GET";
13387 request1.url = GURL(alternative_url);
13388 request1.load_flags = 0;
13389 TestCompletionCallback callback1;
13390
13391 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13392 EXPECT_EQ(OK, callback1.GetResult(rv));
13393 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13394 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5213395 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4213396 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13397 EXPECT_TRUE(response1->was_npn_negotiated);
13398 EXPECT_FALSE(response1->was_fetched_via_spdy);
13399 std::string response_data1;
13400 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
13401 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
13402
13403 // Request for origin.example.org, which has an alternative service. This
13404 // will start two Jobs: the alternative looks for connections to pool to,
13405 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4613406 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4213407 // this request fails.
danakj1fd259a02016-04-16 03:17:0913408 std::unique_ptr<HttpTransaction> trans2(
bnc5452e2a2015-05-08 16:27:4213409 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13410 HttpRequestInfo request2;
13411 request2.method = "GET";
13412 request2.url = GURL(origin_url);
13413 request2.load_flags = 0;
13414 TestCompletionCallback callback2;
13415
13416 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
13417 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
13418
13419 // Another transaction to alternative. This is to test that the HTTP/1.1
13420 // socket is still open and in the pool.
danakj1fd259a02016-04-16 03:17:0913421 std::unique_ptr<HttpTransaction> trans3(
bnc5452e2a2015-05-08 16:27:4213422 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13423 HttpRequestInfo request3;
13424 request3.method = "GET";
13425 request3.url = GURL(alternative_url);
13426 request3.load_flags = 0;
13427 TestCompletionCallback callback3;
13428
13429 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
13430 EXPECT_EQ(OK, callback3.GetResult(rv));
13431 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
13432 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5213433 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4213434 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
13435 EXPECT_TRUE(response3->was_npn_negotiated);
13436 EXPECT_FALSE(response3->was_fetched_via_spdy);
13437 std::string response_data3;
13438 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
13439 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
13440}
13441
[email protected]23e482282013-06-14 16:08:0213442TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2313443 const std::string https_url = "https://www.example.org:8080/";
13444 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413445
rdsmithebb50aa2015-11-12 03:44:3813446 // Separate SPDY util instance for naked and wrapped requests.
13447 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
13448
[email protected]8450d722012-07-02 19:14:0413449 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2313450 const HostPortPair host_port_pair("www.example.org", 8080);
danakj1fd259a02016-04-16 03:17:0913451 std::unique_ptr<SpdySerializedFrame> connect(
lgarrona91df87f2014-12-05 00:51:3413452 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
danakj1fd259a02016-04-16 03:17:0913453 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913454 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
danakj1fd259a02016-04-16 03:17:0913455 std::unique_ptr<SpdySerializedFrame> wrapped_req1(
[email protected]23e482282013-06-14 16:08:0213456 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3913457
13458 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2913459 SpdyHeaderBlock req2_block;
bnc7ecc1122015-09-28 13:22:4913460 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]745aa9c2014-06-27 02:21:2913461 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2313462 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2913463 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4913464 req2_block[spdy_util_.GetPathKey()] = "/";
danakj1fd259a02016-04-16 03:17:0913465 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913466 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0413467
13468 MockWrite writes1[] = {
mmenke666a6fea2015-12-19 04:16:3313469 CreateMockWrite(*connect, 0), CreateMockWrite(*wrapped_req1, 2),
13470 CreateMockWrite(*req2, 6),
[email protected]8450d722012-07-02 19:14:0413471 };
13472
danakj1fd259a02016-04-16 03:17:0913473 std::unique_ptr<SpdySerializedFrame> conn_resp(
bnc38dcd392016-02-09 23:19:4913474 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0913475 std::unique_ptr<SpdySerializedFrame> resp1(
bnc38dcd392016-02-09 23:19:4913476 spdy_util_wrapped.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0913477 std::unique_ptr<SpdySerializedFrame> body1(
bnc38dcd392016-02-09 23:19:4913478 spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913479 std::unique_ptr<SpdySerializedFrame> wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3813480 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
danakj1fd259a02016-04-16 03:17:0913481 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3813482 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
danakj1fd259a02016-04-16 03:17:0913483 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5513484 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913485 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5513486 spdy_util_.ConstructSpdyBodyFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3313487 MockRead reads1[] = {
13488 CreateMockRead(*conn_resp, 1),
13489 MockRead(ASYNC, ERR_IO_PENDING, 3),
13490 CreateMockRead(*wrapped_resp1, 4),
13491 CreateMockRead(*wrapped_body1, 5),
13492 MockRead(ASYNC, ERR_IO_PENDING, 7),
13493 CreateMockRead(*resp2, 8),
13494 CreateMockRead(*body2, 9),
13495 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
13496 };
[email protected]8450d722012-07-02 19:14:0413497
mmenke666a6fea2015-12-19 04:16:3313498 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13499 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413500 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713501 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413502
rdsmith82957ad2015-09-16 19:42:0313503 session_deps_.proxy_service =
13504 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5113505 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713506 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0413507 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3813508 ssl1.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313509 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0413510 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3813511 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313512 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13513 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0413514
danakj1fd259a02016-04-16 03:17:0913515 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0413516
13517 // Start the first transaction to set up the SpdySession
13518 HttpRequestInfo request1;
13519 request1.method = "GET";
13520 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413521 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013522 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413523 TestCompletionCallback callback1;
mmenke666a6fea2015-12-19 04:16:3313524 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0413525
mmenke666a6fea2015-12-19 04:16:3313526 // This pause is a hack to avoid running into https://crbug.com/497228.
13527 data1.RunUntilPaused();
13528 base::RunLoop().RunUntilIdle();
13529 data1.Resume();
13530 EXPECT_EQ(OK, callback1.GetResult(rv));
[email protected]8450d722012-07-02 19:14:0413531 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13532
[email protected]f6c63db52013-02-02 00:35:2213533 LoadTimingInfo load_timing_info1;
13534 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
13535 TestLoadTimingNotReusedWithPac(load_timing_info1,
13536 CONNECT_TIMING_HAS_SSL_TIMES);
13537
mmenke666a6fea2015-12-19 04:16:3313538 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0413539 HttpRequestInfo request2;
13540 request2.method = "GET";
13541 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413542 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013543 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413544 TestCompletionCallback callback2;
mmenke666a6fea2015-12-19 04:16:3313545 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0413546
mmenke666a6fea2015-12-19 04:16:3313547 // This pause is a hack to avoid running into https://crbug.com/497228.
13548 data1.RunUntilPaused();
13549 base::RunLoop().RunUntilIdle();
13550 data1.Resume();
13551 EXPECT_EQ(OK, callback2.GetResult(rv));
13552
[email protected]8450d722012-07-02 19:14:0413553 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2213554
13555 LoadTimingInfo load_timing_info2;
13556 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
13557 // The established SPDY sessions is considered reused by the HTTP request.
13558 TestLoadTimingReusedWithPac(load_timing_info2);
13559 // HTTP requests over a SPDY session should have a different connection
13560 // socket_log_id than requests over a tunnel.
13561 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0413562}
13563
[email protected]2d88e7d2012-07-19 17:55:1713564// Test that in the case where we have a SPDY session to a SPDY proxy
13565// that we do not pool other origins that resolve to the same IP when
13566// the certificate does not match the new origin.
13567// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0213568TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2313569 const std::string url1 = "http://www.example.org/";
13570 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1713571 const std::string ip_addr = "1.2.3.4";
13572
rdsmithebb50aa2015-11-12 03:44:3813573 // Second SpdyTestUtil instance for the second socket.
13574 SpdyTestUtil spdy_util_secure(GetProtocol(), GetDependenciesFromPriority());
13575
[email protected]2d88e7d2012-07-19 17:55:1713576 // SPDY GET for HTTP URL (through SPDY proxy)
danakj1fd259a02016-04-16 03:17:0913577 std::unique_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2313578 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
danakj1fd259a02016-04-16 03:17:0913579 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913580 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1713581
13582 MockWrite writes1[] = {
13583 CreateMockWrite(*req1, 0),
13584 };
13585
danakj1fd259a02016-04-16 03:17:0913586 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5513587 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913588 std::unique_ptr<SpdySerializedFrame> body1(
bncb03b1092016-04-06 11:19:5513589 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1713590 MockRead reads1[] = {
mmenke666a6fea2015-12-19 04:16:3313591 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*resp1, 2),
13592 CreateMockRead(*body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1713593 };
13594
mmenke666a6fea2015-12-19 04:16:3313595 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13596 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3213597 IPAddress ip;
martijn654c8c42016-02-10 22:10:5913598 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1713599 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13600 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3313601 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1713602
13603 // SPDY GET for HTTPS URL (direct)
danakj1fd259a02016-04-16 03:17:0913604 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913605 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1713606
13607 MockWrite writes2[] = {
13608 CreateMockWrite(*req2, 0),
13609 };
13610
danakj1fd259a02016-04-16 03:17:0913611 std::unique_ptr<SpdySerializedFrame> resp2(
rdsmithebb50aa2015-11-12 03:44:3813612 spdy_util_secure.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913613 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5513614 spdy_util_secure.ConstructSpdyBodyFrame(1, true));
mmenke666a6fea2015-12-19 04:16:3313615 MockRead reads2[] = {CreateMockRead(*resp2, 1), CreateMockRead(*body2, 2),
13616 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1713617
mmenke666a6fea2015-12-19 04:16:3313618 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13619 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1713620 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3313621 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1713622
13623 // Set up a proxy config that sends HTTP requests to a proxy, and
13624 // all others direct.
13625 ProxyConfig proxy_config;
13626 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0713627 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0913628 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0413629 NULL));
[email protected]2d88e7d2012-07-19 17:55:1713630
bncce36dca22015-04-21 22:11:2313631 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3813632 ssl1.SetNextProto(GetProtocol());
[email protected]2d88e7d2012-07-19 17:55:1713633 // Load a valid cert. Note, that this does not need to
13634 // be valid for proxy because the MockSSLClientSocket does
13635 // not actually verify it. But SpdySession will use this
13636 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2313637 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5213638 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3313639 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13640 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1713641
13642 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3813643 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313644 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13645 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1713646
[email protected]bb88e1d32013-05-03 23:11:0713647 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2313648 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0713649 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1713650
danakj1fd259a02016-04-16 03:17:0913651 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1713652
13653 // Start the first transaction to set up the SpdySession
13654 HttpRequestInfo request1;
13655 request1.method = "GET";
13656 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1713657 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013658 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713659 TestCompletionCallback callback1;
13660 ASSERT_EQ(ERR_IO_PENDING,
13661 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
mmenke666a6fea2015-12-19 04:16:3313662 // This pause is a hack to avoid running into https://crbug.com/497228.
13663 data1.RunUntilPaused();
13664 base::RunLoop().RunUntilIdle();
13665 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1713666
[email protected]2d88e7d2012-07-19 17:55:1713667 EXPECT_EQ(OK, callback1.WaitForResult());
13668 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13669
13670 // Now, start the HTTP request
13671 HttpRequestInfo request2;
13672 request2.method = "GET";
13673 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1713674 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013675 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713676 TestCompletionCallback callback2;
13677 EXPECT_EQ(ERR_IO_PENDING,
13678 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413679 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1713680
13681 ASSERT_TRUE(callback2.have_result());
13682 EXPECT_EQ(OK, callback2.WaitForResult());
13683 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13684}
13685
[email protected]85f97342013-04-17 06:12:2413686// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
13687// error) in SPDY session, removes the socket from pool and closes the SPDY
13688// session. Verify that new url's from the same HttpNetworkSession (and a new
13689// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0213690TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2313691 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2413692
13693 MockRead reads1[] = {
13694 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
13695 };
13696
mmenke11eb5152015-06-09 14:50:5013697 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2413698
danakj1fd259a02016-04-16 03:17:0913699 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913700 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2413701 MockWrite writes2[] = {
13702 CreateMockWrite(*req2, 0),
13703 };
13704
danakj1fd259a02016-04-16 03:17:0913705 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5513706 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913707 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5513708 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2413709 MockRead reads2[] = {
13710 CreateMockRead(*resp2, 1),
13711 CreateMockRead(*body2, 2),
13712 MockRead(ASYNC, OK, 3) // EOF
13713 };
13714
mmenke11eb5152015-06-09 14:50:5013715 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13716 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2413717
[email protected]85f97342013-04-17 06:12:2413718 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813719 ssl1.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5013720 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13721 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2413722
13723 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813724 ssl2.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5013725 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13726 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2413727
danakj1fd259a02016-04-16 03:17:0913728 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5013729 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2413730
13731 // Start the first transaction to set up the SpdySession and verify that
13732 // connection was closed.
13733 HttpRequestInfo request1;
13734 request1.method = "GET";
13735 request1.url = GURL(https_url);
13736 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013737 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413738 TestCompletionCallback callback1;
13739 EXPECT_EQ(ERR_IO_PENDING,
13740 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413741 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
13742
13743 // Now, start the second request and make sure it succeeds.
13744 HttpRequestInfo request2;
13745 request2.method = "GET";
13746 request2.url = GURL(https_url);
13747 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013748 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2413749 TestCompletionCallback callback2;
13750 EXPECT_EQ(ERR_IO_PENDING,
13751 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2413752
mmenke11eb5152015-06-09 14:50:5013753 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2413754 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13755}
13756
[email protected]23e482282013-06-14 16:08:0213757TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0313758 ClientSocketPoolManager::set_max_sockets_per_group(
13759 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13760 ClientSocketPoolManager::set_max_sockets_per_pool(
13761 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13762
13763 // Use two different hosts with different IPs so they don't get pooled.
13764 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
13765 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0913766 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0313767
13768 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813769 ssl1.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0313770 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813771 ssl2.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0313772 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13774
danakj1fd259a02016-04-16 03:17:0913775 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913776 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0313777 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1313778 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0313779 };
danakj1fd259a02016-04-16 03:17:0913780 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213781 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913782 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213783 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313784 MockRead spdy1_reads[] = {
mmenkee24011922015-12-17 22:12:5913785 CreateMockRead(*host1_resp, 1), CreateMockRead(*host1_resp_body, 2),
13786 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313787 };
13788
rdsmithebb50aa2015-11-12 03:44:3813789 // Use a separate test instance for the separate SpdySession that will be
13790 // created.
13791 SpdyTestUtil spdy_util_2(GetProtocol(), GetDependenciesFromPriority());
danakj1fd259a02016-04-16 03:17:0913792 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1313793 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
13794 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0313795 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
13796
danakj1fd259a02016-04-16 03:17:0913797 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913798 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0313799 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1313800 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0313801 };
danakj1fd259a02016-04-16 03:17:0913802 std::unique_ptr<SpdySerializedFrame> host2_resp(
rdsmithebb50aa2015-11-12 03:44:3813803 spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913804 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
rdsmithebb50aa2015-11-12 03:44:3813805 spdy_util_2.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0313806 MockRead spdy2_reads[] = {
mmenkee24011922015-12-17 22:12:5913807 CreateMockRead(*host2_resp, 1), CreateMockRead(*host2_resp_body, 2),
13808 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0313809 };
13810
danakj1fd259a02016-04-16 03:17:0913811 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1313812 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
13813 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0313814 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
13815
13816 MockWrite http_write[] = {
13817 MockWrite("GET / HTTP/1.1\r\n"
13818 "Host: www.a.com\r\n"
13819 "Connection: keep-alive\r\n\r\n"),
13820 };
13821
13822 MockRead http_read[] = {
13823 MockRead("HTTP/1.1 200 OK\r\n"),
13824 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13825 MockRead("Content-Length: 6\r\n\r\n"),
13826 MockRead("hello!"),
13827 };
13828 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
13829 http_write, arraysize(http_write));
13830 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13831
13832 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4013833 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5313834 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313835 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613836 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313837
13838 TestCompletionCallback callback;
13839 HttpRequestInfo request1;
13840 request1.method = "GET";
13841 request1.url = GURL("https://www.a.com/");
13842 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0913843 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013844 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313845
13846 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
13847 EXPECT_EQ(ERR_IO_PENDING, rv);
13848 EXPECT_EQ(OK, callback.WaitForResult());
13849
13850 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213851 ASSERT_TRUE(response);
13852 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213853 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0313854 EXPECT_TRUE(response->was_fetched_via_spdy);
13855 EXPECT_TRUE(response->was_npn_negotiated);
13856
13857 std::string response_data;
13858 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13859 EXPECT_EQ("hello!", response_data);
13860 trans.reset();
13861 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613862 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313863
13864 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4013865 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5313866 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313867 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613868 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313869 HttpRequestInfo request2;
13870 request2.method = "GET";
13871 request2.url = GURL("https://www.b.com/");
13872 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013873 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313874
13875 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
13876 EXPECT_EQ(ERR_IO_PENDING, rv);
13877 EXPECT_EQ(OK, callback.WaitForResult());
13878
13879 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213880 ASSERT_TRUE(response);
13881 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213882 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0313883 EXPECT_TRUE(response->was_fetched_via_spdy);
13884 EXPECT_TRUE(response->was_npn_negotiated);
13885 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13886 EXPECT_EQ("hello!", response_data);
13887 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613888 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313889 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613890 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313891
13892 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4013893 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5313894 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313895 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613896 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0313897 HttpRequestInfo request3;
13898 request3.method = "GET";
13899 request3.url = GURL("http://www.a.com/");
13900 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013901 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313902
13903 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
13904 EXPECT_EQ(ERR_IO_PENDING, rv);
13905 EXPECT_EQ(OK, callback.WaitForResult());
13906
13907 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213908 ASSERT_TRUE(response);
13909 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0313910 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13911 EXPECT_FALSE(response->was_fetched_via_spdy);
13912 EXPECT_FALSE(response->was_npn_negotiated);
13913 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13914 EXPECT_EQ("hello!", response_data);
13915 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613916 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313917 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613918 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313919}
13920
[email protected]79e1fd62013-06-20 06:50:0413921TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
13922 HttpRequestInfo request;
13923 request.method = "GET";
bncce36dca22015-04-21 22:11:2313924 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413925 request.load_flags = 0;
13926
danakj1fd259a02016-04-16 03:17:0913927 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13928 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113929 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413930
ttuttled9dbc652015-09-29 20:00:5913931 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413932 StaticSocketDataProvider data;
13933 data.set_connect_data(mock_connect);
13934 session_deps_.socket_factory->AddSocketDataProvider(&data);
13935
13936 TestCompletionCallback callback;
13937
13938 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13939 EXPECT_EQ(ERR_IO_PENDING, rv);
13940
13941 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913942 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413943
[email protected]79e1fd62013-06-20 06:50:0413944 // We don't care whether this succeeds or fails, but it shouldn't crash.
13945 HttpRequestHeaders request_headers;
13946 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713947
13948 ConnectionAttempts attempts;
13949 trans->GetConnectionAttempts(&attempts);
13950 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913951 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13952
13953 IPEndPoint endpoint;
13954 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13955 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413956}
13957
13958TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
13959 HttpRequestInfo request;
13960 request.method = "GET";
bncce36dca22015-04-21 22:11:2313961 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413962 request.load_flags = 0;
13963
danakj1fd259a02016-04-16 03:17:0913964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13965 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113966 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413967
ttuttled9dbc652015-09-29 20:00:5913968 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0413969 StaticSocketDataProvider data;
13970 data.set_connect_data(mock_connect);
13971 session_deps_.socket_factory->AddSocketDataProvider(&data);
13972
13973 TestCompletionCallback callback;
13974
13975 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13976 EXPECT_EQ(ERR_IO_PENDING, rv);
13977
13978 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5913979 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0413980
[email protected]79e1fd62013-06-20 06:50:0413981 // We don't care whether this succeeds or fails, but it shouldn't crash.
13982 HttpRequestHeaders request_headers;
13983 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713984
13985 ConnectionAttempts attempts;
13986 trans->GetConnectionAttempts(&attempts);
13987 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5913988 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
13989
13990 IPEndPoint endpoint;
13991 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
13992 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0413993}
13994
13995TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
13996 HttpRequestInfo request;
13997 request.method = "GET";
bncce36dca22015-04-21 22:11:2313998 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413999 request.load_flags = 0;
14000
danakj1fd259a02016-04-16 03:17:0914001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14002 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114003 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414004
14005 MockWrite data_writes[] = {
14006 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14007 };
14008 MockRead data_reads[] = {
14009 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14010 };
14011
14012 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14013 data_writes, arraysize(data_writes));
14014 session_deps_.socket_factory->AddSocketDataProvider(&data);
14015
14016 TestCompletionCallback callback;
14017
14018 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14019 EXPECT_EQ(ERR_IO_PENDING, rv);
14020
14021 rv = callback.WaitForResult();
14022 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14023
[email protected]79e1fd62013-06-20 06:50:0414024 HttpRequestHeaders request_headers;
14025 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14026 EXPECT_TRUE(request_headers.HasHeader("Host"));
14027}
14028
14029TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
14030 HttpRequestInfo request;
14031 request.method = "GET";
bncce36dca22015-04-21 22:11:2314032 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414033 request.load_flags = 0;
14034
danakj1fd259a02016-04-16 03:17:0914035 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14036 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114037 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414038
14039 MockWrite data_writes[] = {
14040 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14041 };
14042 MockRead data_reads[] = {
14043 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14044 };
14045
14046 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14047 data_writes, arraysize(data_writes));
14048 session_deps_.socket_factory->AddSocketDataProvider(&data);
14049
14050 TestCompletionCallback callback;
14051
14052 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14053 EXPECT_EQ(ERR_IO_PENDING, rv);
14054
14055 rv = callback.WaitForResult();
14056 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14057
[email protected]79e1fd62013-06-20 06:50:0414058 HttpRequestHeaders request_headers;
14059 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14060 EXPECT_TRUE(request_headers.HasHeader("Host"));
14061}
14062
14063TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
14064 HttpRequestInfo request;
14065 request.method = "GET";
bncce36dca22015-04-21 22:11:2314066 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414067 request.load_flags = 0;
14068
danakj1fd259a02016-04-16 03:17:0914069 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14070 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114071 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414072
14073 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314074 MockWrite(
14075 "GET / HTTP/1.1\r\n"
14076 "Host: www.example.org\r\n"
14077 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414078 };
14079 MockRead data_reads[] = {
14080 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14081 };
14082
14083 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14084 data_writes, arraysize(data_writes));
14085 session_deps_.socket_factory->AddSocketDataProvider(&data);
14086
14087 TestCompletionCallback callback;
14088
14089 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14090 EXPECT_EQ(ERR_IO_PENDING, rv);
14091
14092 rv = callback.WaitForResult();
14093 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14094
[email protected]79e1fd62013-06-20 06:50:0414095 HttpRequestHeaders request_headers;
14096 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14097 EXPECT_TRUE(request_headers.HasHeader("Host"));
14098}
14099
14100TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
14101 HttpRequestInfo request;
14102 request.method = "GET";
bncce36dca22015-04-21 22:11:2314103 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414104 request.load_flags = 0;
14105
danakj1fd259a02016-04-16 03:17:0914106 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14107 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114108 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414109
14110 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314111 MockWrite(
14112 "GET / HTTP/1.1\r\n"
14113 "Host: www.example.org\r\n"
14114 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414115 };
14116 MockRead data_reads[] = {
14117 MockRead(ASYNC, ERR_CONNECTION_RESET),
14118 };
14119
14120 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14121 data_writes, arraysize(data_writes));
14122 session_deps_.socket_factory->AddSocketDataProvider(&data);
14123
14124 TestCompletionCallback callback;
14125
14126 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14127 EXPECT_EQ(ERR_IO_PENDING, rv);
14128
14129 rv = callback.WaitForResult();
14130 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14131
[email protected]79e1fd62013-06-20 06:50:0414132 HttpRequestHeaders request_headers;
14133 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14134 EXPECT_TRUE(request_headers.HasHeader("Host"));
14135}
14136
14137TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
14138 HttpRequestInfo request;
14139 request.method = "GET";
bncce36dca22015-04-21 22:11:2314140 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414141 request.load_flags = 0;
14142 request.extra_headers.SetHeader("X-Foo", "bar");
14143
danakj1fd259a02016-04-16 03:17:0914144 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14145 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114146 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414147
14148 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314149 MockWrite(
14150 "GET / HTTP/1.1\r\n"
14151 "Host: www.example.org\r\n"
14152 "Connection: keep-alive\r\n"
14153 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414154 };
14155 MockRead data_reads[] = {
14156 MockRead("HTTP/1.1 200 OK\r\n"
14157 "Content-Length: 5\r\n\r\n"
14158 "hello"),
14159 MockRead(ASYNC, ERR_UNEXPECTED),
14160 };
14161
14162 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14163 data_writes, arraysize(data_writes));
14164 session_deps_.socket_factory->AddSocketDataProvider(&data);
14165
14166 TestCompletionCallback callback;
14167
14168 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14169 EXPECT_EQ(ERR_IO_PENDING, rv);
14170
14171 rv = callback.WaitForResult();
14172 EXPECT_EQ(OK, rv);
14173
14174 HttpRequestHeaders request_headers;
14175 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14176 std::string foo;
14177 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14178 EXPECT_EQ("bar", foo);
14179}
14180
[email protected]bf828982013-08-14 18:01:4714181namespace {
14182
yhiranoa7e05bb2014-11-06 05:40:3914183// Fake HttpStream that simply records calls to SetPriority().
14184class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314185 public base::SupportsWeakPtr<FakeStream> {
14186 public:
14187 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014188 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314189
14190 RequestPriority priority() const { return priority_; }
14191
dchengb03027d2014-10-21 12:00:2014192 int InitializeStream(const HttpRequestInfo* request_info,
14193 RequestPriority priority,
14194 const BoundNetLog& net_log,
14195 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314196 return ERR_IO_PENDING;
14197 }
14198
dchengb03027d2014-10-21 12:00:2014199 int SendRequest(const HttpRequestHeaders& request_headers,
14200 HttpResponseInfo* response,
14201 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314202 ADD_FAILURE();
14203 return ERR_UNEXPECTED;
14204 }
14205
dchengb03027d2014-10-21 12:00:2014206 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314207 ADD_FAILURE();
14208 return ERR_UNEXPECTED;
14209 }
14210
dchengb03027d2014-10-21 12:00:2014211 int ReadResponseBody(IOBuffer* buf,
14212 int buf_len,
14213 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314214 ADD_FAILURE();
14215 return ERR_UNEXPECTED;
14216 }
14217
dchengb03027d2014-10-21 12:00:2014218 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314219
dchengb03027d2014-10-21 12:00:2014220 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314221 ADD_FAILURE();
14222 return false;
14223 }
14224
dchengb03027d2014-10-21 12:00:2014225 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314226 ADD_FAILURE();
14227 return false;
14228 }
14229
dchengb03027d2014-10-21 12:00:2014230 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314231
mmenkebd84c392015-09-02 14:12:3414232 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314233
sclittle4de1bab92015-09-22 21:28:2414234 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914235 ADD_FAILURE();
14236 return 0;
14237 }
14238
sclittlebe1ccf62015-09-02 19:40:3614239 int64_t GetTotalSentBytes() const override {
14240 ADD_FAILURE();
14241 return 0;
14242 }
14243
dchengb03027d2014-10-21 12:00:2014244 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314245 ADD_FAILURE();
14246 return false;
14247 }
14248
dchengb03027d2014-10-21 12:00:2014249 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14250
14251 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314252 ADD_FAILURE();
14253 }
14254
ttuttled9dbc652015-09-29 20:00:5914255 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14256
nharperb7441ef2016-01-25 23:54:1414257 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14258 std::vector<uint8_t>* out) override {
14259 ADD_FAILURE();
14260 return ERR_NOT_IMPLEMENTED;
14261 }
14262
dchengb03027d2014-10-21 12:00:2014263 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314264
zhongyica364fbb2015-12-12 03:39:1214265 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14266
dchengb03027d2014-10-21 12:00:2014267 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314268
yhiranoa7e05bb2014-11-06 05:40:3914269 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
14270
14271 HttpStream* RenewStreamForAuth() override { return NULL; }
14272
[email protected]e86839fd2013-08-14 18:29:0314273 private:
14274 RequestPriority priority_;
14275
14276 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14277};
14278
14279// Fake HttpStreamRequest that simply records calls to SetPriority()
14280// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714281class FakeStreamRequest : public HttpStreamRequest,
14282 public base::SupportsWeakPtr<FakeStreamRequest> {
14283 public:
[email protected]e86839fd2013-08-14 18:29:0314284 FakeStreamRequest(RequestPriority priority,
14285 HttpStreamRequest::Delegate* delegate)
14286 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414287 delegate_(delegate),
14288 websocket_stream_create_helper_(NULL) {}
14289
14290 FakeStreamRequest(RequestPriority priority,
14291 HttpStreamRequest::Delegate* delegate,
14292 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14293 : priority_(priority),
14294 delegate_(delegate),
14295 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314296
dchengb03027d2014-10-21 12:00:2014297 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714298
14299 RequestPriority priority() const { return priority_; }
14300
[email protected]831e4a32013-11-14 02:14:4414301 const WebSocketHandshakeStreamBase::CreateHelper*
14302 websocket_stream_create_helper() const {
14303 return websocket_stream_create_helper_;
14304 }
14305
[email protected]e86839fd2013-08-14 18:29:0314306 // Create a new FakeStream and pass it to the request's
14307 // delegate. Returns a weak pointer to the FakeStream.
14308 base::WeakPtr<FakeStream> FinishStreamRequest() {
14309 FakeStream* fake_stream = new FakeStream(priority_);
14310 // Do this before calling OnStreamReady() as OnStreamReady() may
14311 // immediately delete |fake_stream|.
14312 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14313 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14314 return weak_stream;
14315 }
14316
dchengb03027d2014-10-21 12:00:2014317 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714318 ADD_FAILURE();
14319 return ERR_UNEXPECTED;
14320 }
14321
dchengb03027d2014-10-21 12:00:2014322 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714323 ADD_FAILURE();
14324 return LoadState();
14325 }
14326
dchengb03027d2014-10-21 12:00:2014327 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714328
dchengb03027d2014-10-21 12:00:2014329 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714330
dchengb03027d2014-10-21 12:00:2014331 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714332
dchengb03027d2014-10-21 12:00:2014333 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714334
ttuttle1f2d7e92015-04-28 16:17:4714335 const ConnectionAttempts& connection_attempts() const override {
14336 static ConnectionAttempts no_attempts;
14337 return no_attempts;
14338 }
14339
[email protected]bf828982013-08-14 18:01:4714340 private:
14341 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314342 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414343 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714344
14345 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14346};
14347
14348// Fake HttpStreamFactory that vends FakeStreamRequests.
14349class FakeStreamFactory : public HttpStreamFactory {
14350 public:
14351 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014352 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714353
14354 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14355 // RequestStream() (which may be NULL if it was destroyed already).
14356 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14357 return last_stream_request_;
14358 }
14359
dchengb03027d2014-10-21 12:00:2014360 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14361 RequestPriority priority,
14362 const SSLConfig& server_ssl_config,
14363 const SSLConfig& proxy_ssl_config,
14364 HttpStreamRequest::Delegate* delegate,
14365 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314366 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714367 last_stream_request_ = fake_request->AsWeakPtr();
14368 return fake_request;
14369 }
14370
xunjieli5749218c2016-03-22 16:43:0614371 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0814372 const HttpRequestInfo& info,
14373 RequestPriority priority,
14374 const SSLConfig& server_ssl_config,
14375 const SSLConfig& proxy_ssl_config,
14376 HttpStreamRequest::Delegate* delegate,
14377 const BoundNetLog& net_log) override {
14378 NOTREACHED();
14379 return nullptr;
14380 }
14381
dchengb03027d2014-10-21 12:00:2014382 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714383 const HttpRequestInfo& info,
14384 RequestPriority priority,
14385 const SSLConfig& server_ssl_config,
14386 const SSLConfig& proxy_ssl_config,
14387 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614388 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1314389 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414390 FakeStreamRequest* fake_request =
14391 new FakeStreamRequest(priority, delegate, create_helper);
14392 last_stream_request_ = fake_request->AsWeakPtr();
14393 return fake_request;
[email protected]bf828982013-08-14 18:01:4714394 }
14395
dchengb03027d2014-10-21 12:00:2014396 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5914397 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4714398 ADD_FAILURE();
14399 }
14400
dchengb03027d2014-10-21 12:00:2014401 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714402 ADD_FAILURE();
14403 return NULL;
14404 }
14405
14406 private:
14407 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14408
14409 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14410};
14411
Adam Rice425cf122015-01-19 06:18:2414412// TODO(ricea): Maybe unify this with the one in
14413// url_request_http_job_unittest.cc ?
14414class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14415 public:
danakj1fd259a02016-04-16 03:17:0914416 FakeWebSocketBasicHandshakeStream(
14417 std::unique_ptr<ClientSocketHandle> connection,
14418 bool using_proxy)
Adam Rice425cf122015-01-19 06:18:2414419 : state_(connection.release(), using_proxy) {}
14420
14421 // Fake implementation of HttpStreamBase methods.
14422 // This ends up being quite "real" because this object has to really send data
14423 // on the mock socket. It might be easier to use the real implementation, but
14424 // the fact that the WebSocket code is not compiled on iOS makes that
14425 // difficult.
14426 int InitializeStream(const HttpRequestInfo* request_info,
14427 RequestPriority priority,
14428 const BoundNetLog& net_log,
14429 const CompletionCallback& callback) override {
14430 state_.Initialize(request_info, priority, net_log, callback);
14431 return OK;
14432 }
14433
14434 int SendRequest(const HttpRequestHeaders& request_headers,
14435 HttpResponseInfo* response,
14436 const CompletionCallback& callback) override {
14437 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
14438 response, callback);
14439 }
14440
14441 int ReadResponseHeaders(const CompletionCallback& callback) override {
14442 return parser()->ReadResponseHeaders(callback);
14443 }
14444
14445 int ReadResponseBody(IOBuffer* buf,
14446 int buf_len,
14447 const CompletionCallback& callback) override {
14448 NOTREACHED();
14449 return ERR_IO_PENDING;
14450 }
14451
14452 void Close(bool not_reusable) override {
14453 if (parser())
14454 parser()->Close(true);
14455 }
14456
14457 bool IsResponseBodyComplete() const override {
14458 NOTREACHED();
14459 return false;
14460 }
14461
Adam Rice425cf122015-01-19 06:18:2414462 bool IsConnectionReused() const override {
14463 NOTREACHED();
14464 return false;
14465 }
14466 void SetConnectionReused() override { NOTREACHED(); }
14467
mmenkebd84c392015-09-02 14:12:3414468 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2414469
sclittle4de1bab92015-09-22 21:28:2414470 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2414471 NOTREACHED();
14472 return 0;
14473 }
14474
sclittlebe1ccf62015-09-02 19:40:3614475 int64_t GetTotalSentBytes() const override {
14476 NOTREACHED();
14477 return 0;
14478 }
14479
Adam Rice425cf122015-01-19 06:18:2414480 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
14481 NOTREACHED();
14482 return false;
14483 }
14484
Adam Ricecb76ac62015-02-20 05:33:2514485 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2414486
14487 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
14488 NOTREACHED();
14489 }
14490
ttuttled9dbc652015-09-29 20:00:5914491 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14492
nharperb7441ef2016-01-25 23:54:1414493 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14494 std::vector<uint8_t>* out) override {
14495 ADD_FAILURE();
14496 return ERR_NOT_IMPLEMENTED;
14497 }
14498
Adam Rice425cf122015-01-19 06:18:2414499 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
14500
zhongyica364fbb2015-12-12 03:39:1214501 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14502
Adam Rice425cf122015-01-19 06:18:2414503 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
14504
14505 UploadProgress GetUploadProgress() const override {
14506 NOTREACHED();
14507 return UploadProgress();
14508 }
14509
14510 HttpStream* RenewStreamForAuth() override {
14511 NOTREACHED();
14512 return nullptr;
14513 }
14514
14515 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0914516 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2414517 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0914518 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2414519 }
14520
14521 private:
14522 HttpStreamParser* parser() const { return state_.parser(); }
14523 HttpBasicState state_;
14524
14525 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
14526};
14527
[email protected]831e4a32013-11-14 02:14:4414528// TODO(yhirano): Split this class out into a net/websockets file, if it is
14529// worth doing.
14530class FakeWebSocketStreamCreateHelper :
14531 public WebSocketHandshakeStreamBase::CreateHelper {
14532 public:
dchengb03027d2014-10-21 12:00:2014533 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0914534 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1314535 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4814536 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2414537 using_proxy);
[email protected]831e4a32013-11-14 02:14:4414538 }
14539
dchengb03027d2014-10-21 12:00:2014540 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4414541 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1314542 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4414543 NOTREACHED();
14544 return NULL;
14545 };
14546
dchengb03027d2014-10-21 12:00:2014547 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4414548
danakj1fd259a02016-04-16 03:17:0914549 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4414550 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0914551 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4414552 }
14553};
14554
[email protected]bf828982013-08-14 18:01:4714555} // namespace
14556
14557// Make sure that HttpNetworkTransaction passes on its priority to its
14558// stream request on start.
14559TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0914560 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214561 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714562 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0914563 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714564
dcheng48459ac22014-08-26 00:46:4114565 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714566
wezca1070932016-05-26 20:30:5214567 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4714568
14569 HttpRequestInfo request;
14570 TestCompletionCallback callback;
14571 EXPECT_EQ(ERR_IO_PENDING,
14572 trans.Start(&request, callback.callback(), BoundNetLog()));
14573
14574 base::WeakPtr<FakeStreamRequest> fake_request =
14575 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214576 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4714577 EXPECT_EQ(LOW, fake_request->priority());
14578}
14579
14580// Make sure that HttpNetworkTransaction passes on its priority
14581// updates to its stream request.
14582TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0914583 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214584 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714585 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0914586 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714587
dcheng48459ac22014-08-26 00:46:4114588 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714589
14590 HttpRequestInfo request;
14591 TestCompletionCallback callback;
14592 EXPECT_EQ(ERR_IO_PENDING,
14593 trans.Start(&request, callback.callback(), BoundNetLog()));
14594
14595 base::WeakPtr<FakeStreamRequest> fake_request =
14596 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214597 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4714598 EXPECT_EQ(LOW, fake_request->priority());
14599
14600 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5214601 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4714602 EXPECT_EQ(LOWEST, fake_request->priority());
14603}
14604
[email protected]e86839fd2013-08-14 18:29:0314605// Make sure that HttpNetworkTransaction passes on its priority
14606// updates to its stream.
14607TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0914608 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214609 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0314610 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0914611 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0314612
dcheng48459ac22014-08-26 00:46:4114613 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0314614
14615 HttpRequestInfo request;
14616 TestCompletionCallback callback;
14617 EXPECT_EQ(ERR_IO_PENDING,
14618 trans.Start(&request, callback.callback(), BoundNetLog()));
14619
14620 base::WeakPtr<FakeStreamRequest> fake_request =
14621 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214622 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0314623 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5214624 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0314625 EXPECT_EQ(LOW, fake_stream->priority());
14626
14627 trans.SetPriority(LOWEST);
14628 EXPECT_EQ(LOWEST, fake_stream->priority());
14629}
14630
[email protected]831e4a32013-11-14 02:14:4414631TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
14632 // The same logic needs to be tested for both ws: and wss: schemes, but this
14633 // test is already parameterised on NextProto, so it uses a loop to verify
14634 // that the different schemes work.
bncce36dca22015-04-21 22:11:2314635 std::string test_cases[] = {"ws://www.example.org/",
14636 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4414637 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0914638 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4214639 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4414640 FakeStreamFactory* fake_factory = new FakeStreamFactory();
14641 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2314642 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0914643 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4414644
dcheng48459ac22014-08-26 00:46:4114645 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4414646 trans.SetWebSocketHandshakeStreamCreateHelper(
14647 &websocket_stream_create_helper);
14648
14649 HttpRequestInfo request;
14650 TestCompletionCallback callback;
14651 request.method = "GET";
14652 request.url = GURL(test_cases[i]);
14653
14654 EXPECT_EQ(ERR_IO_PENDING,
14655 trans.Start(&request, callback.callback(), BoundNetLog()));
14656
14657 base::WeakPtr<FakeStreamRequest> fake_request =
14658 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5214659 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4414660 EXPECT_EQ(&websocket_stream_create_helper,
14661 fake_request->websocket_stream_create_helper());
14662 }
14663}
14664
[email protected]043b68c82013-08-22 23:41:5214665// Tests that when a used socket is returned to the SSL socket pool, it's closed
14666// if the transport socket pool is stalled on the global socket limit.
14667TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
14668 ClientSocketPoolManager::set_max_sockets_per_group(
14669 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14670 ClientSocketPoolManager::set_max_sockets_per_pool(
14671 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14672
14673 // Set up SSL request.
14674
14675 HttpRequestInfo ssl_request;
14676 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2314677 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214678
14679 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2314680 MockWrite(
14681 "GET / HTTP/1.1\r\n"
14682 "Host: www.example.org\r\n"
14683 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214684 };
14685 MockRead ssl_reads[] = {
14686 MockRead("HTTP/1.1 200 OK\r\n"),
14687 MockRead("Content-Length: 11\r\n\r\n"),
14688 MockRead("hello world"),
14689 MockRead(SYNCHRONOUS, OK),
14690 };
14691 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
14692 ssl_writes, arraysize(ssl_writes));
14693 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14694
14695 SSLSocketDataProvider ssl(ASYNC, OK);
14696 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14697
14698 // Set up HTTP request.
14699
14700 HttpRequestInfo http_request;
14701 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314702 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214703
14704 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314705 MockWrite(
14706 "GET / HTTP/1.1\r\n"
14707 "Host: www.example.org\r\n"
14708 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214709 };
14710 MockRead http_reads[] = {
14711 MockRead("HTTP/1.1 200 OK\r\n"),
14712 MockRead("Content-Length: 7\r\n\r\n"),
14713 MockRead("falafel"),
14714 MockRead(SYNCHRONOUS, OK),
14715 };
14716 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14717 http_writes, arraysize(http_writes));
14718 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14719
danakj1fd259a02016-04-16 03:17:0914720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214721
14722 // Start the SSL request.
14723 TestCompletionCallback ssl_callback;
danakj1fd259a02016-04-16 03:17:0914724 std::unique_ptr<HttpTransaction> ssl_trans(
[email protected]043b68c82013-08-22 23:41:5214725 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14726 ASSERT_EQ(ERR_IO_PENDING,
14727 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
14728 BoundNetLog()));
14729
14730 // Start the HTTP request. Pool should stall.
14731 TestCompletionCallback http_callback;
danakj1fd259a02016-04-16 03:17:0914732 std::unique_ptr<HttpTransaction> http_trans(
[email protected]043b68c82013-08-22 23:41:5214733 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14734 ASSERT_EQ(ERR_IO_PENDING,
14735 http_trans->Start(&http_request, http_callback.callback(),
14736 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4114737 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214738
14739 // Wait for response from SSL request.
14740 ASSERT_EQ(OK, ssl_callback.WaitForResult());
14741 std::string response_data;
14742 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
14743 EXPECT_EQ("hello world", response_data);
14744
14745 // The SSL socket should automatically be closed, so the HTTP request can
14746 // start.
dcheng48459ac22014-08-26 00:46:4114747 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
14748 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214749
14750 // The HTTP request can now complete.
14751 ASSERT_EQ(OK, http_callback.WaitForResult());
14752 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14753 EXPECT_EQ("falafel", response_data);
14754
dcheng48459ac22014-08-26 00:46:4114755 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214756}
14757
14758// Tests that when a SSL connection is established but there's no corresponding
14759// request that needs it, the new socket is closed if the transport socket pool
14760// is stalled on the global socket limit.
14761TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
14762 ClientSocketPoolManager::set_max_sockets_per_group(
14763 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14764 ClientSocketPoolManager::set_max_sockets_per_pool(
14765 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14766
14767 // Set up an ssl request.
14768
14769 HttpRequestInfo ssl_request;
14770 ssl_request.method = "GET";
14771 ssl_request.url = GURL("https://www.foopy.com/");
14772
14773 // No data will be sent on the SSL socket.
14774 StaticSocketDataProvider ssl_data;
14775 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14776
14777 SSLSocketDataProvider ssl(ASYNC, OK);
14778 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14779
14780 // Set up HTTP request.
14781
14782 HttpRequestInfo http_request;
14783 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314784 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214785
14786 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314787 MockWrite(
14788 "GET / HTTP/1.1\r\n"
14789 "Host: www.example.org\r\n"
14790 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214791 };
14792 MockRead http_reads[] = {
14793 MockRead("HTTP/1.1 200 OK\r\n"),
14794 MockRead("Content-Length: 7\r\n\r\n"),
14795 MockRead("falafel"),
14796 MockRead(SYNCHRONOUS, OK),
14797 };
14798 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
14799 http_writes, arraysize(http_writes));
14800 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14801
danakj1fd259a02016-04-16 03:17:0914802 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5214803
14804 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
14805 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2914806 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5914807 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4114808 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214809
14810 // Start the HTTP request. Pool should stall.
14811 TestCompletionCallback http_callback;
danakj1fd259a02016-04-16 03:17:0914812 std::unique_ptr<HttpTransaction> http_trans(
[email protected]043b68c82013-08-22 23:41:5214813 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14814 ASSERT_EQ(ERR_IO_PENDING,
14815 http_trans->Start(&http_request, http_callback.callback(),
14816 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4114817 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5214818
14819 // The SSL connection will automatically be closed once the connection is
14820 // established, to let the HTTP request start.
14821 ASSERT_EQ(OK, http_callback.WaitForResult());
14822 std::string response_data;
14823 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
14824 EXPECT_EQ("falafel", response_data);
14825
dcheng48459ac22014-08-26 00:46:4114826 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5214827}
14828
[email protected]02d74a02014-04-23 18:10:5414829TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0914830 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2214831 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0914832 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2214833 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414834
14835 HttpRequestInfo request;
14836 request.method = "POST";
14837 request.url = GURL("http://www.foo.com/");
14838 request.upload_data_stream = &upload_data_stream;
14839 request.load_flags = 0;
14840
danakj1fd259a02016-04-16 03:17:0914841 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14842 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114843 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414844 // Send headers successfully, but get an error while sending the body.
14845 MockWrite data_writes[] = {
14846 MockWrite("POST / HTTP/1.1\r\n"
14847 "Host: www.foo.com\r\n"
14848 "Connection: keep-alive\r\n"
14849 "Content-Length: 3\r\n\r\n"),
14850 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14851 };
14852
14853 MockRead data_reads[] = {
14854 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14855 MockRead("hello world"),
14856 MockRead(SYNCHRONOUS, OK),
14857 };
14858 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14859 arraysize(data_writes));
14860 session_deps_.socket_factory->AddSocketDataProvider(&data);
14861
14862 TestCompletionCallback callback;
14863
14864 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14865 EXPECT_EQ(ERR_IO_PENDING, rv);
14866
14867 rv = callback.WaitForResult();
14868 EXPECT_EQ(OK, rv);
14869
14870 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214871 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5414872
wezca1070932016-05-26 20:30:5214873 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5414874 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14875
14876 std::string response_data;
14877 rv = ReadTransaction(trans.get(), &response_data);
14878 EXPECT_EQ(OK, rv);
14879 EXPECT_EQ("hello world", response_data);
14880}
14881
14882// This test makes sure the retry logic doesn't trigger when reading an error
14883// response from a server that rejected a POST with a CONNECTION_RESET.
14884TEST_P(HttpNetworkTransactionTest,
14885 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0914886 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5414887 MockWrite data_writes[] = {
14888 MockWrite("GET / HTTP/1.1\r\n"
14889 "Host: www.foo.com\r\n"
14890 "Connection: keep-alive\r\n\r\n"),
14891 MockWrite("POST / HTTP/1.1\r\n"
14892 "Host: www.foo.com\r\n"
14893 "Connection: keep-alive\r\n"
14894 "Content-Length: 3\r\n\r\n"),
14895 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14896 };
14897
14898 MockRead data_reads[] = {
14899 MockRead("HTTP/1.1 200 Peachy\r\n"
14900 "Content-Length: 14\r\n\r\n"),
14901 MockRead("first response"),
14902 MockRead("HTTP/1.1 400 Not OK\r\n"
14903 "Content-Length: 15\r\n\r\n"),
14904 MockRead("second response"),
14905 MockRead(SYNCHRONOUS, OK),
14906 };
14907 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14908 arraysize(data_writes));
14909 session_deps_.socket_factory->AddSocketDataProvider(&data);
14910
14911 TestCompletionCallback callback;
14912 HttpRequestInfo request1;
14913 request1.method = "GET";
14914 request1.url = GURL("http://www.foo.com/");
14915 request1.load_flags = 0;
14916
danakj1fd259a02016-04-16 03:17:0914917 std::unique_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4114918 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414919 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
14920 EXPECT_EQ(ERR_IO_PENDING, rv);
14921
14922 rv = callback.WaitForResult();
14923 EXPECT_EQ(OK, rv);
14924
14925 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5214926 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5414927
wezca1070932016-05-26 20:30:5214928 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5414929 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
14930
14931 std::string response_data1;
14932 rv = ReadTransaction(trans1.get(), &response_data1);
14933 EXPECT_EQ(OK, rv);
14934 EXPECT_EQ("first response", response_data1);
14935 // Delete the transaction to release the socket back into the socket pool.
14936 trans1.reset();
14937
danakj1fd259a02016-04-16 03:17:0914938 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2214939 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0914940 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2214941 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414942
14943 HttpRequestInfo request2;
14944 request2.method = "POST";
14945 request2.url = GURL("http://www.foo.com/");
14946 request2.upload_data_stream = &upload_data_stream;
14947 request2.load_flags = 0;
14948
danakj1fd259a02016-04-16 03:17:0914949 std::unique_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4114950 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414951 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
14952 EXPECT_EQ(ERR_IO_PENDING, rv);
14953
14954 rv = callback.WaitForResult();
14955 EXPECT_EQ(OK, rv);
14956
14957 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:5214958 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5414959
wezca1070932016-05-26 20:30:5214960 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5414961 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
14962
14963 std::string response_data2;
14964 rv = ReadTransaction(trans2.get(), &response_data2);
14965 EXPECT_EQ(OK, rv);
14966 EXPECT_EQ("second response", response_data2);
14967}
14968
14969TEST_P(HttpNetworkTransactionTest,
14970 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0914971 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2214972 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0914973 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2214974 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5414975
14976 HttpRequestInfo request;
14977 request.method = "POST";
14978 request.url = GURL("http://www.foo.com/");
14979 request.upload_data_stream = &upload_data_stream;
14980 request.load_flags = 0;
14981
danakj1fd259a02016-04-16 03:17:0914982 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14983 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114984 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414985 // Send headers successfully, but get an error while sending the body.
14986 MockWrite data_writes[] = {
14987 MockWrite("POST / HTTP/1.1\r\n"
14988 "Host: www.foo.com\r\n"
14989 "Connection: keep-alive\r\n"
14990 "Content-Length: 3\r\n\r\n"
14991 "fo"),
14992 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14993 };
14994
14995 MockRead data_reads[] = {
14996 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14997 MockRead("hello world"),
14998 MockRead(SYNCHRONOUS, OK),
14999 };
15000 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15001 arraysize(data_writes));
15002 session_deps_.socket_factory->AddSocketDataProvider(&data);
15003
15004 TestCompletionCallback callback;
15005
15006 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15007 EXPECT_EQ(ERR_IO_PENDING, rv);
15008
15009 rv = callback.WaitForResult();
15010 EXPECT_EQ(OK, rv);
15011
15012 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215013 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415014
wezca1070932016-05-26 20:30:5215015 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415016 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15017
15018 std::string response_data;
15019 rv = ReadTransaction(trans.get(), &response_data);
15020 EXPECT_EQ(OK, rv);
15021 EXPECT_EQ("hello world", response_data);
15022}
15023
15024// This tests the more common case than the previous test, where headers and
15025// body are not merged into a single request.
15026TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715027 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415028
15029 HttpRequestInfo request;
15030 request.method = "POST";
15031 request.url = GURL("http://www.foo.com/");
15032 request.upload_data_stream = &upload_data_stream;
15033 request.load_flags = 0;
15034
danakj1fd259a02016-04-16 03:17:0915035 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15036 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115037 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415038 // Send headers successfully, but get an error while sending the body.
15039 MockWrite data_writes[] = {
15040 MockWrite("POST / HTTP/1.1\r\n"
15041 "Host: www.foo.com\r\n"
15042 "Connection: keep-alive\r\n"
15043 "Transfer-Encoding: chunked\r\n\r\n"),
15044 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15045 };
15046
15047 MockRead data_reads[] = {
15048 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15049 MockRead("hello world"),
15050 MockRead(SYNCHRONOUS, OK),
15051 };
15052 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15053 arraysize(data_writes));
15054 session_deps_.socket_factory->AddSocketDataProvider(&data);
15055
15056 TestCompletionCallback callback;
15057
15058 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15059 EXPECT_EQ(ERR_IO_PENDING, rv);
15060 // Make sure the headers are sent before adding a chunk. This ensures that
15061 // they can't be merged with the body in a single send. Not currently
15062 // necessary since a chunked body is never merged with headers, but this makes
15063 // the test more future proof.
15064 base::RunLoop().RunUntilIdle();
15065
mmenkecbc2b712014-10-09 20:29:0715066 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415067
15068 rv = callback.WaitForResult();
15069 EXPECT_EQ(OK, rv);
15070
15071 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215072 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415073
wezca1070932016-05-26 20:30:5215074 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415075 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15076
15077 std::string response_data;
15078 rv = ReadTransaction(trans.get(), &response_data);
15079 EXPECT_EQ(OK, rv);
15080 EXPECT_EQ("hello world", response_data);
15081}
15082
15083TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915084 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215085 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915086 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215087 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415088
15089 HttpRequestInfo request;
15090 request.method = "POST";
15091 request.url = GURL("http://www.foo.com/");
15092 request.upload_data_stream = &upload_data_stream;
15093 request.load_flags = 0;
15094
danakj1fd259a02016-04-16 03:17:0915095 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15096 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115097 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415098
15099 MockWrite data_writes[] = {
15100 MockWrite("POST / HTTP/1.1\r\n"
15101 "Host: www.foo.com\r\n"
15102 "Connection: keep-alive\r\n"
15103 "Content-Length: 3\r\n\r\n"),
15104 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15105 };
15106
15107 MockRead data_reads[] = {
15108 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15109 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15110 MockRead("hello world"),
15111 MockRead(SYNCHRONOUS, OK),
15112 };
15113 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15114 arraysize(data_writes));
15115 session_deps_.socket_factory->AddSocketDataProvider(&data);
15116
15117 TestCompletionCallback callback;
15118
15119 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15120 EXPECT_EQ(ERR_IO_PENDING, rv);
15121
15122 rv = callback.WaitForResult();
15123 EXPECT_EQ(OK, rv);
15124
15125 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215126 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415127
wezca1070932016-05-26 20:30:5215128 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415129 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15130
15131 std::string response_data;
15132 rv = ReadTransaction(trans.get(), &response_data);
15133 EXPECT_EQ(OK, rv);
15134 EXPECT_EQ("hello world", response_data);
15135}
15136
15137TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915138 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215139 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915140 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215141 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415142
15143 HttpRequestInfo request;
15144 request.method = "POST";
15145 request.url = GURL("http://www.foo.com/");
15146 request.upload_data_stream = &upload_data_stream;
15147 request.load_flags = 0;
15148
danakj1fd259a02016-04-16 03:17:0915149 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15150 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115151 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415152 // Send headers successfully, but get an error while sending the body.
15153 MockWrite data_writes[] = {
15154 MockWrite("POST / HTTP/1.1\r\n"
15155 "Host: www.foo.com\r\n"
15156 "Connection: keep-alive\r\n"
15157 "Content-Length: 3\r\n\r\n"),
15158 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15159 };
15160
15161 MockRead data_reads[] = {
15162 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15163 MockRead("hello world"),
15164 MockRead(SYNCHRONOUS, OK),
15165 };
15166 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15167 arraysize(data_writes));
15168 session_deps_.socket_factory->AddSocketDataProvider(&data);
15169
15170 TestCompletionCallback callback;
15171
15172 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15173 EXPECT_EQ(ERR_IO_PENDING, rv);
15174
15175 rv = callback.WaitForResult();
15176 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415177}
15178
15179TEST_P(HttpNetworkTransactionTest,
15180 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915181 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215182 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915183 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215184 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415185
15186 HttpRequestInfo request;
15187 request.method = "POST";
15188 request.url = GURL("http://www.foo.com/");
15189 request.upload_data_stream = &upload_data_stream;
15190 request.load_flags = 0;
15191
danakj1fd259a02016-04-16 03:17:0915192 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15193 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115194 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415195 // Send headers successfully, but get an error while sending the body.
15196 MockWrite data_writes[] = {
15197 MockWrite("POST / HTTP/1.1\r\n"
15198 "Host: www.foo.com\r\n"
15199 "Connection: keep-alive\r\n"
15200 "Content-Length: 3\r\n\r\n"),
15201 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15202 };
15203
15204 MockRead data_reads[] = {
15205 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15206 MockRead("HTTP/1.0 302 Redirect\r\n"),
15207 MockRead("Location: http://somewhere-else.com/\r\n"),
15208 MockRead("Content-Length: 0\r\n\r\n"),
15209 MockRead(SYNCHRONOUS, OK),
15210 };
15211 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15212 arraysize(data_writes));
15213 session_deps_.socket_factory->AddSocketDataProvider(&data);
15214
15215 TestCompletionCallback callback;
15216
15217 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15218 EXPECT_EQ(ERR_IO_PENDING, rv);
15219
15220 rv = callback.WaitForResult();
15221 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415222}
15223
15224TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
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 0.9 rocks!"),
15250 MockRead(SYNCHRONOUS, OK),
15251 };
15252 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15253 arraysize(data_writes));
15254 session_deps_.socket_factory->AddSocketDataProvider(&data);
15255
15256 TestCompletionCallback callback;
15257
15258 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15259 EXPECT_EQ(ERR_IO_PENDING, rv);
15260
15261 rv = callback.WaitForResult();
15262 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415263}
15264
15265TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0915266 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215267 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915268 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215269 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415270
15271 HttpRequestInfo request;
15272 request.method = "POST";
15273 request.url = GURL("http://www.foo.com/");
15274 request.upload_data_stream = &upload_data_stream;
15275 request.load_flags = 0;
15276
danakj1fd259a02016-04-16 03:17:0915277 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15278 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115279 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415280 // Send headers successfully, but get an error while sending the body.
15281 MockWrite data_writes[] = {
15282 MockWrite("POST / HTTP/1.1\r\n"
15283 "Host: www.foo.com\r\n"
15284 "Connection: keep-alive\r\n"
15285 "Content-Length: 3\r\n\r\n"),
15286 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15287 };
15288
15289 MockRead data_reads[] = {
15290 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15291 MockRead(SYNCHRONOUS, OK),
15292 };
15293 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15294 arraysize(data_writes));
15295 session_deps_.socket_factory->AddSocketDataProvider(&data);
15296
15297 TestCompletionCallback callback;
15298
15299 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15300 EXPECT_EQ(ERR_IO_PENDING, rv);
15301
15302 rv = callback.WaitForResult();
15303 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415304}
15305
Adam Rice425cf122015-01-19 06:18:2415306// Verify that proxy headers are not sent to the destination server when
15307// establishing a tunnel for a secure WebSocket connection.
15308TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
15309 HttpRequestInfo request;
15310 request.method = "GET";
bncce36dca22015-04-21 22:11:2315311 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415312 AddWebSocketHeaders(&request.extra_headers);
15313
15314 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315315 session_deps_.proxy_service =
15316 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415317
danakj1fd259a02016-04-16 03:17:0915318 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415319
15320 // Since a proxy is configured, try to establish a tunnel.
15321 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715322 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15323 "Host: www.example.org:443\r\n"
15324 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415325
15326 // After calling trans->RestartWithAuth(), this is the request we should
15327 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1715328 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15329 "Host: www.example.org:443\r\n"
15330 "Proxy-Connection: keep-alive\r\n"
15331 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415332
rsleevidb16bb02015-11-12 23:47:1715333 MockWrite("GET / HTTP/1.1\r\n"
15334 "Host: www.example.org\r\n"
15335 "Connection: Upgrade\r\n"
15336 "Upgrade: websocket\r\n"
15337 "Origin: http://www.example.org\r\n"
15338 "Sec-WebSocket-Version: 13\r\n"
15339 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415340 };
15341
15342 // The proxy responds to the connect with a 407, using a persistent
15343 // connection.
15344 MockRead data_reads[] = {
15345 // No credentials.
15346 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15347 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415348 MockRead("Content-Length: 0\r\n"),
15349 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415350
15351 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15352
15353 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15354 MockRead("Upgrade: websocket\r\n"),
15355 MockRead("Connection: Upgrade\r\n"),
15356 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15357 };
15358
15359 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15360 arraysize(data_writes));
15361 session_deps_.socket_factory->AddSocketDataProvider(&data);
15362 SSLSocketDataProvider ssl(ASYNC, OK);
15363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15364
danakj1fd259a02016-04-16 03:17:0915365 std::unique_ptr<HttpTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415366 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15367 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15368 trans->SetWebSocketHandshakeStreamCreateHelper(
15369 &websocket_stream_create_helper);
15370
15371 {
15372 TestCompletionCallback callback;
15373
15374 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15375 EXPECT_EQ(ERR_IO_PENDING, rv);
15376
15377 rv = callback.WaitForResult();
15378 EXPECT_EQ(OK, rv);
15379 }
15380
15381 const HttpResponseInfo* response = trans->GetResponseInfo();
15382 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215383 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415384 EXPECT_EQ(407, response->headers->response_code());
15385
15386 {
15387 TestCompletionCallback callback;
15388
15389 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15390 callback.callback());
15391 EXPECT_EQ(ERR_IO_PENDING, rv);
15392
15393 rv = callback.WaitForResult();
15394 EXPECT_EQ(OK, rv);
15395 }
15396
15397 response = trans->GetResponseInfo();
15398 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215399 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415400
15401 EXPECT_EQ(101, response->headers->response_code());
15402
15403 trans.reset();
15404 session->CloseAllConnections();
15405}
15406
15407// Verify that proxy headers are not sent to the destination server when
15408// establishing a tunnel for an insecure WebSocket connection.
15409// This requires the authentication info to be injected into the auth cache
15410// due to crbug.com/395064
15411// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
15412TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
15413 HttpRequestInfo request;
15414 request.method = "GET";
bncce36dca22015-04-21 22:11:2315415 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415416 AddWebSocketHeaders(&request.extra_headers);
15417
15418 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315419 session_deps_.proxy_service =
15420 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415421
danakj1fd259a02016-04-16 03:17:0915422 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415423
15424 MockWrite data_writes[] = {
15425 // Try to establish a tunnel for the WebSocket connection, with
15426 // credentials. Because WebSockets have a separate set of socket pools,
15427 // they cannot and will not use the same TCP/IP connection as the
15428 // preflight HTTP request.
15429 MockWrite(
bncce36dca22015-04-21 22:11:2315430 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15431 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415432 "Proxy-Connection: keep-alive\r\n"
15433 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15434
15435 MockWrite(
15436 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315437 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415438 "Connection: Upgrade\r\n"
15439 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315440 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415441 "Sec-WebSocket-Version: 13\r\n"
15442 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15443 };
15444
15445 MockRead data_reads[] = {
15446 // HTTP CONNECT with credentials.
15447 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15448
15449 // WebSocket connection established inside tunnel.
15450 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15451 MockRead("Upgrade: websocket\r\n"),
15452 MockRead("Connection: Upgrade\r\n"),
15453 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15454 };
15455
15456 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15457 arraysize(data_writes));
15458 session_deps_.socket_factory->AddSocketDataProvider(&data);
15459
15460 session->http_auth_cache()->Add(
15461 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
15462 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
15463
danakj1fd259a02016-04-16 03:17:0915464 std::unique_ptr<HttpTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415465 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15466 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15467 trans->SetWebSocketHandshakeStreamCreateHelper(
15468 &websocket_stream_create_helper);
15469
15470 TestCompletionCallback callback;
15471
15472 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15473 EXPECT_EQ(ERR_IO_PENDING, rv);
15474
15475 rv = callback.WaitForResult();
15476 EXPECT_EQ(OK, rv);
15477
15478 const HttpResponseInfo* response = trans->GetResponseInfo();
15479 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215480 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415481
15482 EXPECT_EQ(101, response->headers->response_code());
15483
15484 trans.reset();
15485 session->CloseAllConnections();
15486}
15487
sclittlefb249892015-09-10 21:33:2215488TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0915489 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215490 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915491 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215492 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215493
15494 HttpRequestInfo request;
15495 request.method = "POST";
15496 request.url = GURL("http://www.foo.com/");
15497 request.upload_data_stream = &upload_data_stream;
15498
danakj1fd259a02016-04-16 03:17:0915499 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15500 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2215501 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15502 MockWrite data_writes[] = {
15503 MockWrite("POST / HTTP/1.1\r\n"
15504 "Host: www.foo.com\r\n"
15505 "Connection: keep-alive\r\n"
15506 "Content-Length: 3\r\n\r\n"),
15507 MockWrite("foo"),
15508 };
15509
15510 MockRead data_reads[] = {
15511 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15512 MockRead(SYNCHRONOUS, OK),
15513 };
15514 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15515 arraysize(data_writes));
15516 session_deps_.socket_factory->AddSocketDataProvider(&data);
15517
15518 TestCompletionCallback callback;
15519
15520 EXPECT_EQ(ERR_IO_PENDING,
15521 trans->Start(&request, callback.callback(), BoundNetLog()));
15522 EXPECT_EQ(OK, callback.WaitForResult());
15523
15524 std::string response_data;
15525 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15526
15527 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15528 trans->GetTotalSentBytes());
15529 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15530 trans->GetTotalReceivedBytes());
15531}
15532
15533TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0915534 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215535 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915536 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215537 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215538
15539 HttpRequestInfo request;
15540 request.method = "POST";
15541 request.url = GURL("http://www.foo.com/");
15542 request.upload_data_stream = &upload_data_stream;
15543
danakj1fd259a02016-04-16 03:17:0915544 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15545 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2215546 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15547 MockWrite data_writes[] = {
15548 MockWrite("POST / HTTP/1.1\r\n"
15549 "Host: www.foo.com\r\n"
15550 "Connection: keep-alive\r\n"
15551 "Content-Length: 3\r\n\r\n"),
15552 MockWrite("foo"),
15553 };
15554
15555 MockRead data_reads[] = {
15556 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
15557 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15558 MockRead(SYNCHRONOUS, OK),
15559 };
15560 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15561 arraysize(data_writes));
15562 session_deps_.socket_factory->AddSocketDataProvider(&data);
15563
15564 TestCompletionCallback callback;
15565
15566 EXPECT_EQ(ERR_IO_PENDING,
15567 trans->Start(&request, callback.callback(), BoundNetLog()));
15568 EXPECT_EQ(OK, callback.WaitForResult());
15569
15570 std::string response_data;
15571 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15572
15573 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15574 trans->GetTotalSentBytes());
15575 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15576 trans->GetTotalReceivedBytes());
15577}
15578
15579TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2215580 ChunkedUploadDataStream upload_data_stream(0);
15581
15582 HttpRequestInfo request;
15583 request.method = "POST";
15584 request.url = GURL("http://www.foo.com/");
15585 request.upload_data_stream = &upload_data_stream;
15586
danakj1fd259a02016-04-16 03:17:0915587 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15588 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2215589 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15590 // Send headers successfully, but get an error while sending the body.
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 "Transfer-Encoding: chunked\r\n\r\n"),
15596 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
15597 };
15598
15599 MockRead data_reads[] = {
15600 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15601 MockRead(SYNCHRONOUS, OK),
15602 };
15603 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15604 arraysize(data_writes));
15605 session_deps_.socket_factory->AddSocketDataProvider(&data);
15606
15607 TestCompletionCallback callback;
15608
15609 EXPECT_EQ(ERR_IO_PENDING,
15610 trans->Start(&request, callback.callback(), BoundNetLog()));
15611
15612 base::RunLoop().RunUntilIdle();
15613 upload_data_stream.AppendData("f", 1, false);
15614
15615 base::RunLoop().RunUntilIdle();
15616 upload_data_stream.AppendData("oo", 2, true);
15617
15618 EXPECT_EQ(OK, callback.WaitForResult());
15619
15620 std::string response_data;
15621 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15622
15623 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15624 trans->GetTotalSentBytes());
15625 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15626 trans->GetTotalReceivedBytes());
15627}
15628
bncf4588402015-11-24 13:33:1815629TEST_P(HttpNetworkTransactionTest, EnableNPN) {
bncf4588402015-11-24 13:33:1815630 session_deps_.enable_npn = true;
15631
danakj1fd259a02016-04-16 03:17:0915632 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncf4588402015-11-24 13:33:1815633 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
nharper8cdb0fb2016-04-22 21:34:5915634 HttpRequestInfo request;
15635 TestCompletionCallback callback;
15636 EXPECT_EQ(ERR_IO_PENDING,
15637 trans.Start(&request, callback.callback(), BoundNetLog()));
bncf4588402015-11-24 13:33:1815638
15639 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
15640 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15641 EXPECT_THAT(trans.server_ssl_config_.npn_protos,
15642 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15643}
15644
15645TEST_P(HttpNetworkTransactionTest, DisableNPN) {
bncf4588402015-11-24 13:33:1815646 session_deps_.enable_npn = false;
15647
danakj1fd259a02016-04-16 03:17:0915648 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncf4588402015-11-24 13:33:1815649 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
nharper8cdb0fb2016-04-22 21:34:5915650 HttpRequestInfo request;
15651 TestCompletionCallback callback;
15652 EXPECT_EQ(ERR_IO_PENDING,
15653 trans.Start(&request, callback.callback(), BoundNetLog()));
bncf4588402015-11-24 13:33:1815654
15655 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
15656 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15657 EXPECT_TRUE(trans.server_ssl_config_.npn_protos.empty());
15658}
15659
nharperb7441ef2016-01-25 23:54:1415660#if !defined(OS_IOS)
15661TEST_P(HttpNetworkTransactionTest, TokenBindingSpdy) {
15662 const std::string https_url = "https://www.example.com";
15663 HttpRequestInfo request;
15664 request.url = GURL(https_url);
15665 request.method = "GET";
15666
15667 SSLSocketDataProvider ssl(ASYNC, OK);
15668 ssl.token_binding_negotiated = true;
15669 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
15670 ssl.SetNextProto(GetProtocol());
15671 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15672
danakj1fd259a02016-04-16 03:17:0915673 std::unique_ptr<SpdySerializedFrame> resp(
nharperb7441ef2016-01-25 23:54:1415674 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0915675 std::unique_ptr<SpdySerializedFrame> body(
bncb03b1092016-04-06 11:19:5515676 spdy_util_.ConstructSpdyBodyFrame(1, true));
nharperb7441ef2016-01-25 23:54:1415677 MockRead reads[] = {CreateMockRead(*resp), CreateMockRead(*body),
15678 MockRead(ASYNC, ERR_IO_PENDING)};
15679 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
15680 session_deps_.socket_factory->AddSocketDataProvider(&data);
15681 session_deps_.channel_id_service.reset(new ChannelIDService(
15682 new DefaultChannelIDStore(nullptr), base::ThreadTaskRunnerHandle::Get()));
danakj1fd259a02016-04-16 03:17:0915683 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1415684
15685 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15686 TestCompletionCallback callback;
15687 EXPECT_EQ(ERR_IO_PENDING,
15688 trans.Start(&request, callback.callback(), BoundNetLog()));
15689 base::MessageLoop::current()->RunUntilIdle();
15690
15691 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
15692 HttpRequestHeaders headers;
15693 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
15694 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
15695}
15696#endif // !defined(OS_IOS)
15697
[email protected]89ceba9a2009-03-21 03:46:0615698} // namespace net