blob: 7486324cc22a413ddb0c0cbb7253f75a011b7ef1 [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"
mmenke5f94fda2016-06-02 20:54:1357#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5358#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5759#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3860#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2461#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1962#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0763#include "net/log/net_log.h"
vishal.b62985ca92015-04-17 08:45:5164#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4665#include "net/log/test_net_log_entry.h"
66#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1367#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5368#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0369#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1170#include "net/proxy/proxy_resolver.h"
tbansal28e68f82016-02-04 02:56:1571#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1172#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4473#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1574#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0375#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4776#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0277#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0778#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4479#include "net/socket/socket_test_util.h"
80#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5481#include "net/spdy/spdy_framer.h"
82#include "net/spdy/spdy_session.h"
83#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0284#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1485#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5786#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0387#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5788#include "net/ssl/ssl_config_service_defaults.h"
89#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5490#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1191#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4492#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:1893#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:5294#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1595#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2796#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5297
[email protected]ad65a3e2013-12-25 18:18:0198using base::ASCIIToUTF16;
99
initial.commit586acc5fe2008-07-26 22:42:52100//-----------------------------------------------------------------------------
101
ttuttle859dc7a2015-04-23 19:42:29102namespace net {
103
[email protected]13c8a092010-07-29 06:15:44104namespace {
105
rdsmithebb50aa2015-11-12 03:44:38106enum TestCase {
107 // Test using the SPDY/3.1 protocol.
108 kTestCaseSPDY31,
109
110 // Test using the HTTP/2 protocol, without specifying a stream
111 // dependency based on the RequestPriority.
112 kTestCaseHTTP2NoPriorityDependencies,
113
114 // Test using the HTTP/2 protocol, specifying a stream
115 // dependency based on the RequestPriority.
116 kTestCaseHTTP2PriorityDependencies
117};
118
[email protected]42cba2fb2013-03-29 19:58:57119const base::string16 kBar(ASCIIToUTF16("bar"));
120const base::string16 kBar2(ASCIIToUTF16("bar2"));
121const base::string16 kBar3(ASCIIToUTF16("bar3"));
122const base::string16 kBaz(ASCIIToUTF16("baz"));
123const base::string16 kFirst(ASCIIToUTF16("first"));
124const base::string16 kFoo(ASCIIToUTF16("foo"));
125const base::string16 kFoo2(ASCIIToUTF16("foo2"));
126const base::string16 kFoo3(ASCIIToUTF16("foo3"));
127const base::string16 kFou(ASCIIToUTF16("fou"));
128const base::string16 kSecond(ASCIIToUTF16("second"));
129const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
130const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44131
ttuttle859dc7a2015-04-23 19:42:29132int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
133 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
134 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02135}
136
ttuttle859dc7a2015-04-23 19:42:29137int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
138 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
139 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02140}
141
ttuttle859dc7a2015-04-23 19:42:29142bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
143 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
144 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52145}
146
[email protected]f3da152d2012-06-02 01:00:57147// Takes in a Value created from a NetLogHttpResponseParameter, and returns
148// a JSONified list of headers as a single string. Uses single quotes instead
149// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27150bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57151 if (!params)
152 return false;
[email protected]ea5ef4c2013-06-13 22:50:27153 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57154 if (!params->GetList("headers", &header_list))
155 return false;
156 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34157 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28158 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57159 return true;
160}
161
[email protected]029c83b62013-01-24 05:28:20162// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
163// used.
ttuttle859dc7a2015-04-23 19:42:29164void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20165 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29166 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25167
[email protected]029c83b62013-01-24 05:28:20168 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
169 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
170
ttuttle859dc7a2015-04-23 19:42:29171 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20172 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25173
174 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25175
[email protected]3b23a222013-05-15 21:33:25176 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25177 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
178 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25179 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25180}
181
[email protected]029c83b62013-01-24 05:28:20182// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
183// used.
ttuttle859dc7a2015-04-23 19:42:29184void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25185 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20186 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29187 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20188
189 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
190 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
191
ttuttle859dc7a2015-04-23 19:42:29192 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
193 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20194 EXPECT_LE(load_timing_info.connect_timing.connect_end,
195 load_timing_info.send_start);
196
197 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20198
[email protected]3b23a222013-05-15 21:33:25199 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20200 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
201 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25202 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20203}
204
205// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
206// used.
ttuttle859dc7a2015-04-23 19:42:29207void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20208 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29209 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20210
ttuttle859dc7a2015-04-23 19:42:29211 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20212
213 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
214 EXPECT_LE(load_timing_info.proxy_resolve_start,
215 load_timing_info.proxy_resolve_end);
216 EXPECT_LE(load_timing_info.proxy_resolve_end,
217 load_timing_info.send_start);
218 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20219
[email protected]3b23a222013-05-15 21:33:25220 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20221 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
222 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25223 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20224}
225
226// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
227// used.
ttuttle859dc7a2015-04-23 19:42:29228void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20229 int connect_timing_flags) {
230 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29231 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20232
233 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
234 EXPECT_LE(load_timing_info.proxy_resolve_start,
235 load_timing_info.proxy_resolve_end);
236 EXPECT_LE(load_timing_info.proxy_resolve_end,
237 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29238 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
239 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20240 EXPECT_LE(load_timing_info.connect_timing.connect_end,
241 load_timing_info.send_start);
242
243 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20244
[email protected]3b23a222013-05-15 21:33:25245 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20246 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
247 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25248 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25249}
250
ttuttle859dc7a2015-04-23 19:42:29251void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24252 headers->SetHeader("Connection", "Upgrade");
253 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23254 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24255 headers->SetHeader("Sec-WebSocket-Version", "13");
256 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
257}
258
danakj1fd259a02016-04-16 03:17:09259std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42260 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34261 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14262}
263
[email protected]448d4ca52012-03-04 04:12:23264} // namespace
265
[email protected]23e482282013-06-14 16:08:02266class HttpNetworkTransactionTest
267 : public PlatformTest,
rdsmithebb50aa2015-11-12 03:44:38268 public ::testing::WithParamInterface<TestCase> {
[email protected]483fa202013-05-14 01:07:03269 public:
[email protected]23e482282013-06-14 16:08:02270 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03271 // Important to restore the per-pool limit first, since the pool limit must
272 // always be greater than group limit, and the tests reduce both limits.
273 ClientSocketPoolManager::set_max_sockets_per_pool(
274 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
275 ClientSocketPoolManager::set_max_sockets_per_group(
276 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
277 }
278
[email protected]e3ceb682011-06-28 23:55:46279 protected:
[email protected]23e482282013-06-14 16:08:02280 HttpNetworkTransactionTest()
rdsmithebb50aa2015-11-12 03:44:38281 : spdy_util_(GetProtocol(), GetDependenciesFromPriority()),
282 session_deps_(GetProtocol()),
[email protected]483fa202013-05-14 01:07:03283 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
284 HttpNetworkSession::NORMAL_SOCKET_POOL)),
285 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
286 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
rdsmith2e54d1f2016-03-21 19:48:17287 session_deps_.enable_priority_dependencies = GetDependenciesFromPriority();
[email protected]483fa202013-05-14 01:07:03288 }
[email protected]bb88e1d32013-05-03 23:11:07289
[email protected]e3ceb682011-06-28 23:55:46290 struct SimpleGetHelperResult {
291 int rv;
292 std::string status_line;
293 std::string response_data;
sclittlefb249892015-09-10 21:33:22294 int64_t total_received_bytes;
295 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25296 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47297 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59298 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46299 };
300
dcheng67be2b1f2014-10-27 21:47:29301 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50302 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55303 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54304 }
305
dcheng67be2b1f2014-10-27 21:47:29306 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50307 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55308 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09309 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55310 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09311 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50312 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55313 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09314 }
315
rdsmithebb50aa2015-11-12 03:44:38316 NextProto GetProtocol() const {
317 return GetParam() == kTestCaseSPDY31 ? kProtoSPDY31 : kProtoHTTP2;
318 }
319
320 bool GetDependenciesFromPriority() const {
321 return GetParam() == kTestCaseHTTP2PriorityDependencies;
322 }
323
bnc33b8cef42014-11-19 17:30:38324 const char* GetAlternateProtocolFromParam() {
rdsmithebb50aa2015-11-12 03:44:38325 return AlternateProtocolToString(
326 AlternateProtocolFromNextProto(GetProtocol()));
bnc33b8cef42014-11-19 17:30:38327 }
328
bncc958faa2015-07-31 18:14:52329 std::string GetAlternativeServiceHttpHeader() {
330 return std::string("Alt-Svc: ") + GetAlternateProtocolFromParam() +
bnc8bef8da22016-05-30 01:28:25331 "=\"www.example.org:443\"\r\n";
bncc958faa2015-07-31 18:14:52332 }
333
[email protected]202965992011-12-07 23:04:51334 // Either |write_failure| specifies a write failure or |read_failure|
335 // specifies a read failure when using a reused socket. In either case, the
336 // failure should cause the network transaction to resend the request, and the
337 // other argument should be NULL.
338 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
339 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52340
[email protected]a34f61ee2014-03-18 20:59:49341 // Either |write_failure| specifies a write failure or |read_failure|
342 // specifies a read failure when using a reused socket. In either case, the
343 // failure should cause the network transaction to resend the request, and the
344 // other argument should be NULL.
345 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10346 const MockRead* read_failure,
347 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49348
[email protected]5a60c8b2011-10-19 20:14:29349 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
350 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15351 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52352
[email protected]ff007e162009-05-23 09:13:15353 HttpRequestInfo request;
354 request.method = "GET";
bncce36dca22015-04-21 22:11:23355 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15356 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52357
vishal.b62985ca92015-04-17 08:45:51358 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07359 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09360 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
361 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41362 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27363
[email protected]5a60c8b2011-10-19 20:14:29364 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07365 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29366 }
initial.commit586acc5fe2008-07-26 22:42:52367
[email protected]49639fa2011-12-20 23:22:41368 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52369
eroman24bc6a12015-05-06 19:55:48370 EXPECT_TRUE(log.bound().IsCapturing());
[email protected]49639fa2011-12-20 23:22:41371 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15372 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52373
[email protected]ff007e162009-05-23 09:13:15374 out.rv = callback.WaitForResult();
sclittlefb249892015-09-10 21:33:22375 out.total_received_bytes = trans->GetTotalReceivedBytes();
376 out.total_sent_bytes = trans->GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25377
378 // Even in the failure cases that use this function, connections are always
379 // successfully established before the error.
380 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
381 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
382
[email protected]ff007e162009-05-23 09:13:15383 if (out.rv != OK)
384 return out;
385
386 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50387 // Can't use ASSERT_* inside helper functions like this, so
388 // return an error.
wezca1070932016-05-26 20:30:52389 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50390 out.rv = ERR_UNEXPECTED;
391 return out;
392 }
[email protected]ff007e162009-05-23 09:13:15393 out.status_line = response->headers->GetStatusLine();
394
[email protected]80a09a82012-11-16 17:40:06395 EXPECT_EQ("127.0.0.1", response->socket_address.host());
396 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19397
ttuttled9dbc652015-09-29 20:00:59398 bool got_endpoint =
399 trans->GetRemoteEndpoint(&out.remote_endpoint_after_start);
400 EXPECT_EQ(got_endpoint,
401 out.remote_endpoint_after_start.address().size() > 0);
402
[email protected]ff007e162009-05-23 09:13:15403 rv = ReadTransaction(trans.get(), &out.response_data);
404 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40405
mmenke43758e62015-05-04 21:09:46406 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40407 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39408 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40409 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12410 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39411 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40412 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39413 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
414 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15415
[email protected]f3da152d2012-06-02 01:00:57416 std::string line;
417 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
418 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
419
[email protected]79e1fd62013-06-20 06:50:04420 HttpRequestHeaders request_headers;
421 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
422 std::string value;
423 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23424 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04425 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
426 EXPECT_EQ("keep-alive", value);
427
428 std::string response_headers;
429 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23430 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04431 response_headers);
[email protected]3deb9a52010-11-11 00:24:40432
sclittlefb249892015-09-10 21:33:22433 out.total_received_bytes = trans->GetTotalReceivedBytes();
434 // The total number of sent bytes should not have changed.
435 EXPECT_EQ(out.total_sent_bytes, trans->GetTotalSentBytes());
436
ttuttle1f2d7e92015-04-28 16:17:47437 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47438 return out;
[email protected]ff007e162009-05-23 09:13:15439 }
initial.commit586acc5fe2008-07-26 22:42:52440
[email protected]5a60c8b2011-10-19 20:14:29441 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
442 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22443 MockWrite data_writes[] = {
444 MockWrite("GET / HTTP/1.1\r\n"
445 "Host: www.example.org\r\n"
446 "Connection: keep-alive\r\n\r\n"),
447 };
[email protected]5a60c8b2011-10-19 20:14:29448
sclittlefb249892015-09-10 21:33:22449 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
450 arraysize(data_writes));
451 StaticSocketDataProvider* data[] = {&reads};
452 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
453
454 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
455 out.total_sent_bytes);
456 return out;
[email protected]b8015c42013-12-24 15:18:19457 }
458
[email protected]ff007e162009-05-23 09:13:15459 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
460 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52461
[email protected]ff007e162009-05-23 09:13:15462 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07463
464 void BypassHostCacheOnRefreshHelper(int load_flags);
465
466 void CheckErrorIsPassedBack(int error, IoMode mode);
467
[email protected]4bd46222013-05-14 19:32:23468 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07469 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03470
471 // Original socket limits. Some tests set these. Safest to always restore
472 // them once each test has been run.
473 int old_max_group_sockets_;
474 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15475};
[email protected]231d5a32008-09-13 00:45:27476
rdsmithebb50aa2015-11-12 03:44:38477INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc57685ae62015-03-10 21:27:20478 HttpNetworkTransactionTest,
rdsmithebb50aa2015-11-12 03:44:38479 testing::Values(kTestCaseSPDY31,
480 kTestCaseHTTP2NoPriorityDependencies,
481 kTestCaseHTTP2PriorityDependencies));
[email protected]23e482282013-06-14 16:08:02482
[email protected]448d4ca52012-03-04 04:12:23483namespace {
484
[email protected]1826a402014-01-08 15:40:48485class BeforeNetworkStartHandler {
486 public:
487 explicit BeforeNetworkStartHandler(bool defer)
488 : defer_on_before_network_start_(defer),
489 observed_before_network_start_(false) {}
490
491 void OnBeforeNetworkStart(bool* defer) {
492 *defer = defer_on_before_network_start_;
493 observed_before_network_start_ = true;
494 }
495
496 bool observed_before_network_start() const {
497 return observed_before_network_start_;
498 }
499
500 private:
501 const bool defer_on_before_network_start_;
502 bool observed_before_network_start_;
503
504 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
505};
506
ryansturm49a8cb12016-06-15 16:51:09507class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27508 public:
ryansturm49a8cb12016-06-15 16:51:09509 BeforeHeadersSentHandler()
510 : observed_before_headers_sent_with_proxy_(false),
511 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27512
ryansturm49a8cb12016-06-15 16:51:09513 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
514 HttpRequestHeaders* request_headers) {
515 observed_before_headers_sent_ = true;
516 if (!proxy_info.is_http() && !proxy_info.is_https() &&
517 !proxy_info.is_quic()) {
518 return;
519 }
520 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27521 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
522 }
523
ryansturm49a8cb12016-06-15 16:51:09524 bool observed_before_headers_sent_with_proxy() const {
525 return observed_before_headers_sent_with_proxy_;
526 }
527
528 bool observed_before_headers_sent() const {
529 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27530 }
531
532 std::string observed_proxy_server_uri() const {
533 return observed_proxy_server_uri_;
534 }
535
536 private:
ryansturm49a8cb12016-06-15 16:51:09537 bool observed_before_headers_sent_with_proxy_;
538 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27539 std::string observed_proxy_server_uri_;
540
ryansturm49a8cb12016-06-15 16:51:09541 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27542};
543
[email protected]15a5ccf82008-10-23 19:57:43544// Fill |str| with a long header list that consumes >= |size| bytes.
545void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51546 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19547 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
548 const int sizeof_row = strlen(row);
549 const int num_rows = static_cast<int>(
550 ceil(static_cast<float>(size) / sizeof_row));
551 const int sizeof_data = num_rows * sizeof_row;
552 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43553 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51554
[email protected]4ddaf2502008-10-23 18:26:19555 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43556 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19557}
558
thakis84dff942015-07-28 20:47:38559#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29560// Alternative functions that eliminate randomness and dependency on the local
561// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14562void MockGenerateRandom1(uint8_t* output, size_t n) {
563 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
564 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29565 static size_t current_byte = 0;
566 for (size_t i = 0; i < n; ++i) {
567 output[i] = bytes[current_byte++];
568 current_byte %= arraysize(bytes);
569 }
570}
571
avibf0746c2015-12-09 19:53:14572void MockGenerateRandom2(uint8_t* output, size_t n) {
573 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
574 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
575 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29576 static size_t current_byte = 0;
577 for (size_t i = 0; i < n; ++i) {
578 output[i] = bytes[current_byte++];
579 current_byte %= arraysize(bytes);
580 }
581}
582
[email protected]fe2bc6a2009-03-23 16:52:20583std::string MockGetHostName() {
584 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29585}
thakis84dff942015-07-28 20:47:38586#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29587
[email protected]e60e47a2010-07-14 03:37:18588template<typename ParentPool>
589class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31590 public:
[email protected]9e1bdd32011-02-03 21:48:34591 CaptureGroupNameSocketPool(HostResolver* host_resolver,
592 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18593
[email protected]d80a4322009-08-14 07:07:49594 const std::string last_group_name_received() const {
595 return last_group_name_;
596 }
597
dmichaeld6e570d2014-12-18 22:30:57598 int RequestSocket(const std::string& group_name,
599 const void* socket_params,
600 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15601 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57602 ClientSocketHandle* handle,
603 const CompletionCallback& callback,
604 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31605 last_group_name_ = group_name;
606 return ERR_IO_PENDING;
607 }
dmichaeld6e570d2014-12-18 22:30:57608 void CancelRequest(const std::string& group_name,
609 ClientSocketHandle* handle) override {}
610 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09611 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57612 int id) override {}
613 void CloseIdleSockets() override {}
614 int IdleSocketCount() const override { return 0; }
615 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31616 return 0;
617 }
dmichaeld6e570d2014-12-18 22:30:57618 LoadState GetLoadState(const std::string& group_name,
619 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31620 return LOAD_STATE_IDLE;
621 }
dmichaeld6e570d2014-12-18 22:30:57622 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26623 return base::TimeDelta();
624 }
[email protected]d80a4322009-08-14 07:07:49625
626 private:
[email protected]04e5be32009-06-26 20:00:31627 std::string last_group_name_;
628};
629
[email protected]ab739042011-04-07 15:22:28630typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
631CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13632typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
633CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06634typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11635CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18636typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
637CaptureGroupNameSSLSocketPool;
638
rkaplowd90695c2015-03-25 22:12:41639template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18640CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34641 HostResolver* host_resolver,
642 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21643 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18644
hashimoto0d3e4fb2015-01-09 05:02:50645template <>
[email protected]2df19bb2010-08-25 20:13:46646CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21647 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34648 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41649 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50650}
[email protected]2df19bb2010-08-25 20:13:46651
[email protected]007b3f82013-04-09 08:46:45652template <>
[email protected]e60e47a2010-07-14 03:37:18653CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21654 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34655 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45656 : SSLClientSocketPool(0,
657 0,
[email protected]007b3f82013-04-09 08:46:45658 cert_verifier,
659 NULL,
660 NULL,
[email protected]284303b62013-11-28 15:11:54661 NULL,
eranm6571b2b2014-12-03 15:53:23662 NULL,
[email protected]007b3f82013-04-09 08:46:45663 std::string(),
664 NULL,
665 NULL,
666 NULL,
667 NULL,
668 NULL,
[email protected]8e458552014-08-05 00:02:15669 NULL) {
670}
[email protected]2227c692010-05-04 15:36:11671
[email protected]231d5a32008-09-13 00:45:27672//-----------------------------------------------------------------------------
673
[email protected]79cb5c12011-09-12 13:12:04674// Helper functions for validating that AuthChallengeInfo's are correctly
675// configured for common cases.
676bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
677 if (!auth_challenge)
678 return false;
679 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43680 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04681 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19682 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04683 return true;
684}
685
686bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
687 if (!auth_challenge)
688 return false;
689 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43690 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
691 EXPECT_EQ("MyRealm1", auth_challenge->realm);
692 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
693 return true;
694}
695
696bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
697 if (!auth_challenge)
698 return false;
699 EXPECT_TRUE(auth_challenge->is_proxy);
700 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04701 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19702 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04703 return true;
704}
705
706bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
707 if (!auth_challenge)
708 return false;
709 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43710 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04711 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19712 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04713 return true;
714}
715
thakis84dff942015-07-28 20:47:38716#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04717bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
718 if (!auth_challenge)
719 return false;
720 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43721 EXPECT_EQ("http://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04722 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19723 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04724 return true;
725}
thakis84dff942015-07-28 20:47:38726#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04727
[email protected]448d4ca52012-03-04 04:12:23728} // namespace
729
[email protected]23e482282013-06-14 16:08:02730TEST_P(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
732 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41733 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27734}
735
[email protected]23e482282013-06-14 16:08:02736TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27737 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35738 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
739 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06740 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27741 };
[email protected]31a2bfe2010-02-09 08:03:39742 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
743 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42744 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27745 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
746 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22747 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
748 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47749 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59750
751 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27752}
753
754// Response with no status line.
[email protected]23e482282013-06-14 16:08:02755TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27756 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35757 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06758 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27759 };
[email protected]31a2bfe2010-02-09 08:03:39760 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
761 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42762 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27763 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
764 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22765 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
766 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27767}
768
769// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02770TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27771 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35772 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06773 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27774 };
[email protected]31a2bfe2010-02-09 08:03:39775 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
776 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42777 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27778 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
779 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22780 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
781 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27782}
783
784// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02785TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27786 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35787 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06788 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27789 };
[email protected]31a2bfe2010-02-09 08:03:39790 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
791 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42792 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27793 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
794 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22795 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
796 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27797}
798
799// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02800TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27801 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35802 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06803 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27804 };
[email protected]31a2bfe2010-02-09 08:03:39805 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
806 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42807 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25808 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
809 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
sclittlefb249892015-09-10 21:33:22810 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
811 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27812}
813
814// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02815TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27816 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35817 MockRead("\n"),
818 MockRead("\n"),
819 MockRead("Q"),
820 MockRead("J"),
821 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06822 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27823 };
[email protected]31a2bfe2010-02-09 08:03:39824 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
825 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42826 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27827 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
828 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22829 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
830 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27831}
832
833// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02834TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27835 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35836 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06837 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27838 };
[email protected]31a2bfe2010-02-09 08:03:39839 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
840 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42841 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27842 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
843 EXPECT_EQ("HTT", out.response_data);
sclittlefb249892015-09-10 21:33:22844 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
845 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52846}
847
[email protected]f9d44aa2008-09-23 23:57:17848// Simulate a 204 response, lacking a Content-Length header, sent over a
849// persistent connection. The response should still terminate since a 204
850// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02851TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19852 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17853 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35854 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19855 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06856 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17857 };
[email protected]31a2bfe2010-02-09 08:03:39858 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
859 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42860 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17861 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
862 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22863 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
864 int64_t response_size = reads_size - strlen(junk);
865 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17866}
867
[email protected]0877e3d2009-10-17 22:29:57868// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02869TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19870 std::string final_chunk = "0\r\n\r\n";
871 std::string extra_data = "HTTP/1.1 200 OK\r\n";
872 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57873 MockRead data_reads[] = {
874 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
875 MockRead("5\r\nHello\r\n"),
876 MockRead("1\r\n"),
877 MockRead(" \r\n"),
878 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19879 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06880 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57881 };
[email protected]31a2bfe2010-02-09 08:03:39882 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
883 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57884 EXPECT_EQ(OK, out.rv);
885 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
886 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22887 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
888 int64_t response_size = reads_size - extra_data.size();
889 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57890}
891
[email protected]9fe44f52010-09-23 18:36:00892// Next tests deal with http://crbug.com/56344.
893
[email protected]23e482282013-06-14 16:08:02894TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00895 MultipleContentLengthHeadersNoTransferEncoding) {
896 MockRead data_reads[] = {
897 MockRead("HTTP/1.1 200 OK\r\n"),
898 MockRead("Content-Length: 10\r\n"),
899 MockRead("Content-Length: 5\r\n\r\n"),
900 };
901 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
902 arraysize(data_reads));
903 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
904}
905
[email protected]23e482282013-06-14 16:08:02906TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04907 DuplicateContentLengthHeadersNoTransferEncoding) {
908 MockRead data_reads[] = {
909 MockRead("HTTP/1.1 200 OK\r\n"),
910 MockRead("Content-Length: 5\r\n"),
911 MockRead("Content-Length: 5\r\n\r\n"),
912 MockRead("Hello"),
913 };
914 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
915 arraysize(data_reads));
916 EXPECT_EQ(OK, out.rv);
917 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
918 EXPECT_EQ("Hello", out.response_data);
919}
920
[email protected]23e482282013-06-14 16:08:02921TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04922 ComplexContentLengthHeadersNoTransferEncoding) {
923 // More than 2 dupes.
924 {
925 MockRead data_reads[] = {
926 MockRead("HTTP/1.1 200 OK\r\n"),
927 MockRead("Content-Length: 5\r\n"),
928 MockRead("Content-Length: 5\r\n"),
929 MockRead("Content-Length: 5\r\n\r\n"),
930 MockRead("Hello"),
931 };
932 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
933 arraysize(data_reads));
934 EXPECT_EQ(OK, out.rv);
935 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
936 EXPECT_EQ("Hello", out.response_data);
937 }
938 // HTTP/1.0
939 {
940 MockRead data_reads[] = {
941 MockRead("HTTP/1.0 200 OK\r\n"),
942 MockRead("Content-Length: 5\r\n"),
943 MockRead("Content-Length: 5\r\n"),
944 MockRead("Content-Length: 5\r\n\r\n"),
945 MockRead("Hello"),
946 };
947 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
948 arraysize(data_reads));
949 EXPECT_EQ(OK, out.rv);
950 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
951 EXPECT_EQ("Hello", out.response_data);
952 }
953 // 2 dupes and one mismatched.
954 {
955 MockRead data_reads[] = {
956 MockRead("HTTP/1.1 200 OK\r\n"),
957 MockRead("Content-Length: 10\r\n"),
958 MockRead("Content-Length: 10\r\n"),
959 MockRead("Content-Length: 5\r\n\r\n"),
960 };
961 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
962 arraysize(data_reads));
963 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
964 }
965}
966
[email protected]23e482282013-06-14 16:08:02967TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00968 MultipleContentLengthHeadersTransferEncoding) {
969 MockRead data_reads[] = {
970 MockRead("HTTP/1.1 200 OK\r\n"),
971 MockRead("Content-Length: 666\r\n"),
972 MockRead("Content-Length: 1337\r\n"),
973 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
974 MockRead("5\r\nHello\r\n"),
975 MockRead("1\r\n"),
976 MockRead(" \r\n"),
977 MockRead("5\r\nworld\r\n"),
978 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06979 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00980 };
981 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
982 arraysize(data_reads));
983 EXPECT_EQ(OK, out.rv);
984 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
985 EXPECT_EQ("Hello world", out.response_data);
986}
987
[email protected]1628fe92011-10-04 23:04:55988// Next tests deal with http://crbug.com/98895.
989
990// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02991TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55992 MockRead data_reads[] = {
993 MockRead("HTTP/1.1 200 OK\r\n"),
994 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
995 MockRead("Content-Length: 5\r\n\r\n"),
996 MockRead("Hello"),
997 };
998 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
999 arraysize(data_reads));
1000 EXPECT_EQ(OK, out.rv);
1001 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1002 EXPECT_EQ("Hello", out.response_data);
1003}
1004
[email protected]54a9c6e52012-03-21 20:10:591005// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:021006TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:591007 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551008 MockRead data_reads[] = {
1009 MockRead("HTTP/1.1 200 OK\r\n"),
1010 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1011 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1012 MockRead("Content-Length: 5\r\n\r\n"),
1013 MockRead("Hello"),
1014 };
1015 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1016 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:591017 EXPECT_EQ(OK, out.rv);
1018 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1019 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551020}
1021
1022// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:021023TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551024 MockRead data_reads[] = {
1025 MockRead("HTTP/1.1 200 OK\r\n"),
1026 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1027 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1028 MockRead("Content-Length: 5\r\n\r\n"),
1029 MockRead("Hello"),
1030 };
1031 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1032 arraysize(data_reads));
1033 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
1034}
1035
[email protected]54a9c6e52012-03-21 20:10:591036// Checks that two identical Location headers result in no error.
1037// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:021038TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551039 MockRead data_reads[] = {
1040 MockRead("HTTP/1.1 302 Redirect\r\n"),
1041 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591042 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551043 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061044 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551045 };
1046
1047 HttpRequestInfo request;
1048 request.method = "GET";
1049 request.url = GURL("http://redirect.com/");
1050 request.load_flags = 0;
1051
danakj1fd259a02016-04-16 03:17:091052 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1053 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411054 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:551055
1056 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071057 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551058
[email protected]49639fa2011-12-20 23:22:411059 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551060
[email protected]49639fa2011-12-20 23:22:411061 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:551062 EXPECT_EQ(ERR_IO_PENDING, rv);
1063
1064 EXPECT_EQ(OK, callback.WaitForResult());
1065
1066 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521067 ASSERT_TRUE(response);
1068 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551069 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1070 std::string url;
1071 EXPECT_TRUE(response->headers->IsRedirect(&url));
1072 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151073 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551074}
1075
[email protected]1628fe92011-10-04 23:04:551076// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021077TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551078 MockRead data_reads[] = {
1079 MockRead("HTTP/1.1 302 Redirect\r\n"),
1080 MockRead("Location: http://good.com/\r\n"),
1081 MockRead("Location: http://evil.com/\r\n"),
1082 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061083 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551084 };
1085 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1086 arraysize(data_reads));
1087 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1088}
1089
[email protected]ef0faf2e72009-03-05 23:27:231090// Do a request using the HEAD method. Verify that we don't try to read the
1091// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021092TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421093 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231094 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231095 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231096 request.load_flags = 0;
1097
danakj1fd259a02016-04-16 03:17:091098 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1099 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411100 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ryansturm49a8cb12016-06-15 16:51:091101 BeforeHeadersSentHandler headers_handler;
1102 trans->SetBeforeHeadersSentCallback(
1103 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1104 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271105
[email protected]ef0faf2e72009-03-05 23:27:231106 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131107 MockWrite("HEAD / HTTP/1.1\r\n"
1108 "Host: www.example.org\r\n"
1109 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231110 };
1111 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231112 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1113 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231114
mmenked39192ee2015-12-09 00:57:231115 // No response body because the test stops reading here.
1116 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231117 };
1118
[email protected]31a2bfe2010-02-09 08:03:391119 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1120 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071121 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231122
[email protected]49639fa2011-12-20 23:22:411123 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231124
[email protected]49639fa2011-12-20 23:22:411125 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421126 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231127
1128 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421129 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231130
[email protected]1c773ea12009-04-28 19:58:421131 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521132 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231133
1134 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521135 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231136 EXPECT_EQ(1234, response->headers->GetContentLength());
1137 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151138 EXPECT_TRUE(response->proxy_server.IsEmpty());
ryansturm49a8cb12016-06-15 16:51:091139 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1140 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231141
1142 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101143 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231144 bool has_server_header = response->headers->EnumerateHeader(
1145 &iter, "Server", &server_header);
1146 EXPECT_TRUE(has_server_header);
1147 EXPECT_EQ("Blah", server_header);
1148
1149 // Reading should give EOF right away, since there is no message body
1150 // (despite non-zero content-length).
1151 std::string response_data;
1152 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421153 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231154 EXPECT_EQ("", response_data);
1155}
1156
[email protected]23e482282013-06-14 16:08:021157TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521159
1160 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351161 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1162 MockRead("hello"),
1163 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1164 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061165 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521166 };
[email protected]31a2bfe2010-02-09 08:03:391167 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071168 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521169
[email protected]0b0bf032010-09-21 18:08:501170 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521171 "hello", "world"
1172 };
1173
1174 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421175 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521176 request.method = "GET";
bncce36dca22015-04-21 22:11:231177 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521178 request.load_flags = 0;
1179
danakj1fd259a02016-04-16 03:17:091180 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501181 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271182
[email protected]49639fa2011-12-20 23:22:411183 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521184
[email protected]49639fa2011-12-20 23:22:411185 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421186 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521187
1188 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421189 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521190
[email protected]1c773ea12009-04-28 19:58:421191 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521192 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521193
wezca1070932016-05-26 20:30:521194 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251195 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151196 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521197
1198 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571199 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421200 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251201 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521202 }
1203}
1204
[email protected]23e482282013-06-14 16:08:021205TEST_P(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091206 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221207 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:091208 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:221209 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271210
[email protected]1c773ea12009-04-28 19:58:421211 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521212 request.method = "POST";
1213 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271214 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521215 request.load_flags = 0;
1216
danakj1fd259a02016-04-16 03:17:091217 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1218 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411219 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271220
initial.commit586acc5fe2008-07-26 22:42:521221 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351222 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1223 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1224 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061225 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521226 };
[email protected]31a2bfe2010-02-09 08:03:391227 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071228 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521229
[email protected]49639fa2011-12-20 23:22:411230 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521231
[email protected]49639fa2011-12-20 23:22:411232 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421233 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521234
1235 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421236 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521237
[email protected]1c773ea12009-04-28 19:58:421238 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521239 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521240
wezca1070932016-05-26 20:30:521241 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251242 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521243
1244 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571245 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421246 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251247 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521248}
1249
[email protected]3a2d3662009-03-27 03:49:141250// This test is almost the same as Ignores100 above, but the response contains
1251// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571252// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021253TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421254 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141255 request.method = "GET";
1256 request.url = GURL("http://www.foo.com/");
1257 request.load_flags = 0;
1258
danakj1fd259a02016-04-16 03:17:091259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1260 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411261 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271262
[email protected]3a2d3662009-03-27 03:49:141263 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571264 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1265 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141266 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061267 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141268 };
[email protected]31a2bfe2010-02-09 08:03:391269 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071270 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141271
[email protected]49639fa2011-12-20 23:22:411272 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141273
[email protected]49639fa2011-12-20 23:22:411274 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421275 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141276
1277 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421278 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141279
[email protected]1c773ea12009-04-28 19:58:421280 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521281 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141282
wezca1070932016-05-26 20:30:521283 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141284 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1285
1286 std::string response_data;
1287 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421288 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141289 EXPECT_EQ("hello world", response_data);
1290}
1291
[email protected]23e482282013-06-14 16:08:021292TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081293 HttpRequestInfo request;
1294 request.method = "POST";
1295 request.url = GURL("http://www.foo.com/");
1296 request.load_flags = 0;
1297
danakj1fd259a02016-04-16 03:17:091298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1299 std::unique_ptr<HttpTransaction> trans(
zmo9528c9f42015-08-04 22:12:081300 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1301
1302 MockRead data_reads[] = {
1303 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1304 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381305 };
zmo9528c9f42015-08-04 22:12:081306 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1307 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381308
zmo9528c9f42015-08-04 22:12:081309 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381310
zmo9528c9f42015-08-04 22:12:081311 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1312 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381313
zmo9528c9f42015-08-04 22:12:081314 rv = callback.WaitForResult();
1315 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381316
zmo9528c9f42015-08-04 22:12:081317 std::string response_data;
1318 rv = ReadTransaction(trans.get(), &response_data);
1319 EXPECT_EQ(OK, rv);
1320 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381321}
1322
[email protected]23e482282013-06-14 16:08:021323TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381324 HttpRequestInfo request;
1325 request.method = "POST";
1326 request.url = GURL("http://www.foo.com/");
1327 request.load_flags = 0;
1328
danakj1fd259a02016-04-16 03:17:091329 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1330 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411331 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271332
[email protected]ee9410e72010-01-07 01:42:381333 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061334 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381335 };
[email protected]31a2bfe2010-02-09 08:03:391336 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071337 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381338
[email protected]49639fa2011-12-20 23:22:411339 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381340
[email protected]49639fa2011-12-20 23:22:411341 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381342 EXPECT_EQ(ERR_IO_PENDING, rv);
1343
1344 rv = callback.WaitForResult();
1345 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1346}
1347
[email protected]23e482282013-06-14 16:08:021348void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511349 const MockWrite* write_failure,
1350 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421351 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521352 request.method = "GET";
1353 request.url = GURL("http://www.foo.com/");
1354 request.load_flags = 0;
1355
vishal.b62985ca92015-04-17 08:45:511356 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071357 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091358 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271359
[email protected]202965992011-12-07 23:04:511360 // Written data for successfully sending both requests.
1361 MockWrite data1_writes[] = {
1362 MockWrite("GET / HTTP/1.1\r\n"
1363 "Host: www.foo.com\r\n"
1364 "Connection: keep-alive\r\n\r\n"),
1365 MockWrite("GET / HTTP/1.1\r\n"
1366 "Host: www.foo.com\r\n"
1367 "Connection: keep-alive\r\n\r\n")
1368 };
1369
1370 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521371 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351372 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1373 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061374 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521375 };
[email protected]202965992011-12-07 23:04:511376
1377 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491378 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511379 data1_writes[1] = *write_failure;
1380 } else {
1381 ASSERT_TRUE(read_failure);
1382 data1_reads[2] = *read_failure;
1383 }
1384
1385 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1386 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071387 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521388
1389 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351390 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1391 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061392 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521393 };
[email protected]31a2bfe2010-02-09 08:03:391394 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071395 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521396
thestig9d3bb0c2015-01-24 00:49:511397 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521398 "hello", "world"
1399 };
1400
avibf0746c2015-12-09 19:53:141401 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521402 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411403 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521404
danakj1fd259a02016-04-16 03:17:091405 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501406 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521407
[email protected]49639fa2011-12-20 23:22:411408 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421409 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521410
1411 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421412 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521413
[email protected]58e32bb2013-01-21 18:23:251414 LoadTimingInfo load_timing_info;
1415 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1416 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1417 if (i == 0) {
1418 first_socket_log_id = load_timing_info.socket_log_id;
1419 } else {
1420 // The second request should be using a new socket.
1421 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1422 }
1423
[email protected]1c773ea12009-04-28 19:58:421424 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521425 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521426
wezca1070932016-05-26 20:30:521427 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251428 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521429
1430 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571431 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421432 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251433 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521434 }
1435}
[email protected]3d2a59b2008-09-26 19:44:251436
[email protected]a34f61ee2014-03-18 20:59:491437void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1438 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101439 const MockRead* read_failure,
1440 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491441 HttpRequestInfo request;
1442 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101443 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491444 request.load_flags = 0;
1445
vishal.b62985ca92015-04-17 08:45:511446 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491447 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491449
[email protected]09356c652014-03-25 15:36:101450 SSLSocketDataProvider ssl1(ASYNC, OK);
1451 SSLSocketDataProvider ssl2(ASYNC, OK);
1452 if (use_spdy) {
rdsmithebb50aa2015-11-12 03:44:381453 ssl1.SetNextProto(GetProtocol());
1454 ssl2.SetNextProto(GetProtocol());
[email protected]09356c652014-03-25 15:36:101455 }
1456 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1457 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491458
[email protected]09356c652014-03-25 15:36:101459 // SPDY versions of the request and response.
danakj1fd259a02016-04-16 03:17:091460 std::unique_ptr<SpdySerializedFrame> spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491461 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
danakj1fd259a02016-04-16 03:17:091462 std::unique_ptr<SpdySerializedFrame> spdy_response(
[email protected]09356c652014-03-25 15:36:101463 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:091464 std::unique_ptr<SpdySerializedFrame> spdy_data(
[email protected]09356c652014-03-25 15:36:101465 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491466
[email protected]09356c652014-03-25 15:36:101467 // HTTP/1.1 versions of the request and response.
1468 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1469 "Host: www.foo.com\r\n"
1470 "Connection: keep-alive\r\n\r\n";
1471 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1472 const char kHttpData[] = "hello";
1473
1474 std::vector<MockRead> data1_reads;
1475 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491476 if (write_failure) {
1477 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101478 data1_writes.push_back(*write_failure);
1479 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491480 } else {
1481 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101482 if (use_spdy) {
1483 data1_writes.push_back(CreateMockWrite(*spdy_request));
1484 } else {
1485 data1_writes.push_back(MockWrite(kHttpRequest));
1486 }
1487 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491488 }
1489
[email protected]09356c652014-03-25 15:36:101490 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1491 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491492 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1493
[email protected]09356c652014-03-25 15:36:101494 std::vector<MockRead> data2_reads;
1495 std::vector<MockWrite> data2_writes;
1496
1497 if (use_spdy) {
1498 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1499
1500 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1501 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1502 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1503 } else {
1504 data2_writes.push_back(
1505 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1506
1507 data2_reads.push_back(
1508 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1509 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1510 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1511 }
rch8e6c6c42015-05-01 14:05:131512 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1513 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491514 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1515
1516 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591517 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491518 // Wait for the preconnect to complete.
1519 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1520 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101521 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491522
1523 // Make the request.
1524 TestCompletionCallback callback;
1525
danakj1fd259a02016-04-16 03:17:091526 std::unique_ptr<HttpTransaction> trans(
[email protected]a34f61ee2014-03-18 20:59:491527 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1528
1529 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1530 EXPECT_EQ(ERR_IO_PENDING, rv);
1531
1532 rv = callback.WaitForResult();
1533 EXPECT_EQ(OK, rv);
1534
1535 LoadTimingInfo load_timing_info;
1536 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101537 TestLoadTimingNotReused(
1538 load_timing_info,
1539 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491540
1541 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521542 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491543
wezca1070932016-05-26 20:30:521544 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021545 if (response->was_fetched_via_spdy) {
1546 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1547 } else {
1548 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1549 }
[email protected]a34f61ee2014-03-18 20:59:491550
1551 std::string response_data;
1552 rv = ReadTransaction(trans.get(), &response_data);
1553 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101554 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491555}
1556
[email protected]23e482282013-06-14 16:08:021557TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231558 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061559 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511560 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1561}
1562
[email protected]23e482282013-06-14 16:08:021563TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061564 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511565 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251566}
1567
[email protected]23e482282013-06-14 16:08:021568TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061569 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511570 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251571}
1572
[email protected]d58ceea82014-06-04 10:55:541573// Make sure that on a 408 response (Request Timeout), the request is retried,
1574// if the socket was a reused keep alive socket.
1575TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1576 MockRead read_failure(SYNCHRONOUS,
1577 "HTTP/1.1 408 Request Timeout\r\n"
1578 "Connection: Keep-Alive\r\n"
1579 "Content-Length: 6\r\n\r\n"
1580 "Pickle");
1581 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1582}
1583
[email protected]a34f61ee2014-03-18 20:59:491584TEST_P(HttpNetworkTransactionTest,
1585 PreconnectErrorNotConnectedOnWrite) {
1586 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101587 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491588}
1589
1590TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1591 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101592 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491593}
1594
1595TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1596 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101597 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1598}
1599
1600TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1601 MockRead read_failure(ASYNC, OK); // EOF
1602 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1603}
1604
[email protected]d58ceea82014-06-04 10:55:541605// Make sure that on a 408 response (Request Timeout), the request is retried,
1606// if the socket was a preconnected (UNUSED_IDLE) socket.
1607TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1608 MockRead read_failure(SYNCHRONOUS,
1609 "HTTP/1.1 408 Request Timeout\r\n"
1610 "Connection: Keep-Alive\r\n"
1611 "Content-Length: 6\r\n\r\n"
1612 "Pickle");
1613 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1614 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1615}
1616
[email protected]09356c652014-03-25 15:36:101617TEST_P(HttpNetworkTransactionTest,
1618 SpdyPreconnectErrorNotConnectedOnWrite) {
1619 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1620 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1621}
1622
1623TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1624 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1625 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1626}
1627
1628TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1629 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1630 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1631}
1632
1633TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1634 MockRead read_failure(ASYNC, OK); // EOF
1635 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491636}
1637
[email protected]23e482282013-06-14 16:08:021638TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421639 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251640 request.method = "GET";
bncce36dca22015-04-21 22:11:231641 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251642 request.load_flags = 0;
1643
danakj1fd259a02016-04-16 03:17:091644 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1645 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411646 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271647
[email protected]3d2a59b2008-09-26 19:44:251648 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061649 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351650 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1651 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061652 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251653 };
[email protected]31a2bfe2010-02-09 08:03:391654 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071655 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251656
[email protected]49639fa2011-12-20 23:22:411657 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251658
[email protected]49639fa2011-12-20 23:22:411659 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421660 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251661
1662 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421663 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:591664
1665 IPEndPoint endpoint;
1666 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
1667 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251668}
1669
1670// What do various browsers do when the server closes a non-keepalive
1671// connection without sending any response header or body?
1672//
1673// IE7: error page
1674// Safari 3.1.2 (Windows): error page
1675// Firefox 3.0.1: blank page
1676// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421677// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1678// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021679TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251680 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061681 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351682 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1683 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061684 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251685 };
[email protected]31a2bfe2010-02-09 08:03:391686 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1687 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421688 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251689}
[email protected]038e9a32008-10-08 22:40:161690
[email protected]1826a402014-01-08 15:40:481691// Test that network access can be deferred and resumed.
1692TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1693 HttpRequestInfo request;
1694 request.method = "GET";
bncce36dca22015-04-21 22:11:231695 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481696 request.load_flags = 0;
1697
danakj1fd259a02016-04-16 03:17:091698 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1699 std::unique_ptr<HttpTransaction> trans(
[email protected]1826a402014-01-08 15:40:481700 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1701
1702 // Defer on OnBeforeNetworkStart.
1703 BeforeNetworkStartHandler net_start_handler(true); // defer
1704 trans->SetBeforeNetworkStartCallback(
1705 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1706 base::Unretained(&net_start_handler)));
1707
1708 MockRead data_reads[] = {
1709 MockRead("HTTP/1.0 200 OK\r\n"),
1710 MockRead("Content-Length: 5\r\n\r\n"),
1711 MockRead("hello"),
1712 MockRead(SYNCHRONOUS, 0),
1713 };
1714 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1715 session_deps_.socket_factory->AddSocketDataProvider(&data);
1716
1717 TestCompletionCallback callback;
1718
1719 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1720 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:551721 base::RunLoop().RunUntilIdle();
[email protected]1826a402014-01-08 15:40:481722
1723 // Should have deferred for network start.
1724 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1725 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481726
1727 trans->ResumeNetworkStart();
1728 rv = callback.WaitForResult();
1729 EXPECT_EQ(OK, rv);
wezca1070932016-05-26 20:30:521730 EXPECT_TRUE(trans->GetResponseInfo());
[email protected]1826a402014-01-08 15:40:481731
1732 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1733 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1734 if (rv == ERR_IO_PENDING)
1735 rv = callback.WaitForResult();
1736 EXPECT_EQ(5, rv);
1737 trans.reset();
1738}
1739
1740// Test that network use can be deferred and canceled.
1741TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1742 HttpRequestInfo request;
1743 request.method = "GET";
bncce36dca22015-04-21 22:11:231744 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481745 request.load_flags = 0;
1746
danakj1fd259a02016-04-16 03:17:091747 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1748 std::unique_ptr<HttpTransaction> trans(
[email protected]1826a402014-01-08 15:40:481749 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1750
1751 // Defer on OnBeforeNetworkStart.
1752 BeforeNetworkStartHandler net_start_handler(true); // defer
1753 trans->SetBeforeNetworkStartCallback(
1754 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1755 base::Unretained(&net_start_handler)));
1756
1757 TestCompletionCallback callback;
1758
1759 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1760 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:551761 base::RunLoop().RunUntilIdle();
[email protected]1826a402014-01-08 15:40:481762
1763 // Should have deferred for network start.
1764 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1765 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481766}
1767
[email protected]7a5378b2012-11-04 03:25:171768// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1769// tests. There was a bug causing HttpNetworkTransaction to hang in the
1770// destructor in such situations.
1771// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021772TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171773 HttpRequestInfo request;
1774 request.method = "GET";
bncce36dca22015-04-21 22:11:231775 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171776 request.load_flags = 0;
1777
danakj1fd259a02016-04-16 03:17:091778 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1779 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501780 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171781
1782 MockRead data_reads[] = {
1783 MockRead("HTTP/1.0 200 OK\r\n"),
1784 MockRead("Connection: keep-alive\r\n"),
1785 MockRead("Content-Length: 100\r\n\r\n"),
1786 MockRead("hello"),
1787 MockRead(SYNCHRONOUS, 0),
1788 };
1789 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071790 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171791
1792 TestCompletionCallback callback;
1793
1794 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1795 EXPECT_EQ(ERR_IO_PENDING, rv);
1796
1797 rv = callback.WaitForResult();
1798 EXPECT_EQ(OK, rv);
1799
1800 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501801 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171802 if (rv == ERR_IO_PENDING)
1803 rv = callback.WaitForResult();
1804 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501805 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171806 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1807
1808 trans.reset();
fdoray92e35a72016-06-10 15:54:551809 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171810 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1811}
1812
[email protected]23e482282013-06-14 16:08:021813TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171814 HttpRequestInfo request;
1815 request.method = "GET";
bncce36dca22015-04-21 22:11:231816 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171817 request.load_flags = 0;
1818
danakj1fd259a02016-04-16 03:17:091819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1820 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501821 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171822
1823 MockRead data_reads[] = {
1824 MockRead("HTTP/1.0 200 OK\r\n"),
1825 MockRead("Connection: keep-alive\r\n"),
1826 MockRead("Content-Length: 100\r\n\r\n"),
1827 MockRead(SYNCHRONOUS, 0),
1828 };
1829 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071830 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171831
1832 TestCompletionCallback callback;
1833
1834 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1835 EXPECT_EQ(ERR_IO_PENDING, rv);
1836
1837 rv = callback.WaitForResult();
1838 EXPECT_EQ(OK, rv);
1839
1840 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501841 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171842 if (rv == ERR_IO_PENDING)
1843 rv = callback.WaitForResult();
1844 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1845
1846 trans.reset();
fdoray92e35a72016-06-10 15:54:551847 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171848 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1849}
1850
[email protected]0b0bf032010-09-21 18:08:501851// Test that we correctly reuse a keep-alive connection after not explicitly
1852// reading the body.
[email protected]23e482282013-06-14 16:08:021853TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131854 HttpRequestInfo request;
1855 request.method = "GET";
1856 request.url = GURL("http://www.foo.com/");
1857 request.load_flags = 0;
1858
vishal.b62985ca92015-04-17 08:45:511859 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071860 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271862
mmenkecc2298e2015-12-07 18:20:181863 const char* request_data =
1864 "GET / HTTP/1.1\r\n"
1865 "Host: www.foo.com\r\n"
1866 "Connection: keep-alive\r\n\r\n";
1867 MockWrite data_writes[] = {
1868 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1869 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1870 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1871 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1872 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1873 };
1874
[email protected]0b0bf032010-09-21 18:08:501875 // Note that because all these reads happen in the same
1876 // StaticSocketDataProvider, it shows that the same socket is being reused for
1877 // all transactions.
mmenkecc2298e2015-12-07 18:20:181878 MockRead data_reads[] = {
1879 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1880 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1881 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1882 MockRead(ASYNC, 7,
1883 "HTTP/1.1 302 Found\r\n"
1884 "Content-Length: 0\r\n\r\n"),
1885 MockRead(ASYNC, 9,
1886 "HTTP/1.1 302 Found\r\n"
1887 "Content-Length: 5\r\n\r\n"
1888 "hello"),
1889 MockRead(ASYNC, 11,
1890 "HTTP/1.1 301 Moved Permanently\r\n"
1891 "Content-Length: 0\r\n\r\n"),
1892 MockRead(ASYNC, 13,
1893 "HTTP/1.1 301 Moved Permanently\r\n"
1894 "Content-Length: 5\r\n\r\n"
1895 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131896
mmenkecc2298e2015-12-07 18:20:181897 // In the next two rounds, IsConnectedAndIdle returns false, due to
1898 // the set_busy_before_sync_reads(true) call, while the
1899 // HttpNetworkTransaction is being shut down, but the socket is still
1900 // reuseable. See http://crbug.com/544255.
1901 MockRead(ASYNC, 15,
1902 "HTTP/1.1 200 Hunky-Dory\r\n"
1903 "Content-Length: 5\r\n\r\n"),
1904 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131905
mmenkecc2298e2015-12-07 18:20:181906 MockRead(ASYNC, 18,
1907 "HTTP/1.1 200 Hunky-Dory\r\n"
1908 "Content-Length: 5\r\n\r\n"
1909 "he"),
1910 MockRead(SYNCHRONOUS, 19, "llo"),
1911
1912 // The body of the final request is actually read.
1913 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1914 MockRead(ASYNC, 22, "hello"),
1915 };
1916 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1917 arraysize(data_writes));
1918 data.set_busy_before_sync_reads(true);
1919 session_deps_.socket_factory->AddSocketDataProvider(&data);
1920
1921 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501922 std::string response_lines[kNumUnreadBodies];
1923
avibf0746c2015-12-09 19:53:141924 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181925 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411926 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131927
danakj1fd259a02016-04-16 03:17:091928 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501929 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131930
[email protected]49639fa2011-12-20 23:22:411931 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
mmenkecc2298e2015-12-07 18:20:181932 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]fc31d6a42010-06-24 18:05:131933
[email protected]58e32bb2013-01-21 18:23:251934 LoadTimingInfo load_timing_info;
1935 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1936 if (i == 0) {
1937 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1938 first_socket_log_id = load_timing_info.socket_log_id;
1939 } else {
1940 TestLoadTimingReused(load_timing_info);
1941 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1942 }
1943
[email protected]fc31d6a42010-06-24 18:05:131944 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181945 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131946
mmenkecc2298e2015-12-07 18:20:181947 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501948 response_lines[i] = response->headers->GetStatusLine();
1949
mmenkecc2298e2015-12-07 18:20:181950 // Delete the transaction without reading the response bodies. Then spin
1951 // the message loop, so the response bodies are drained.
1952 trans.reset();
1953 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131954 }
[email protected]0b0bf032010-09-21 18:08:501955
1956 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181957 "HTTP/1.1 204 No Content",
1958 "HTTP/1.1 205 Reset Content",
1959 "HTTP/1.1 304 Not Modified",
1960 "HTTP/1.1 302 Found",
1961 "HTTP/1.1 302 Found",
1962 "HTTP/1.1 301 Moved Permanently",
1963 "HTTP/1.1 301 Moved Permanently",
1964 "HTTP/1.1 200 Hunky-Dory",
1965 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:501966 };
1967
mostynb91e0da982015-01-20 19:17:271968 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1969 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501970
1971 for (int i = 0; i < kNumUnreadBodies; ++i)
1972 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1973
[email protected]49639fa2011-12-20 23:22:411974 TestCompletionCallback callback;
danakj1fd259a02016-04-16 03:17:091975 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501976 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411977 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
mmenkecc2298e2015-12-07 18:20:181978 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]0b0bf032010-09-21 18:08:501979 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181980 ASSERT_TRUE(response);
1981 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501982 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1983 std::string response_data;
1984 rv = ReadTransaction(trans.get(), &response_data);
1985 EXPECT_EQ(OK, rv);
1986 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131987}
1988
mmenke5f94fda2016-06-02 20:54:131989// Sockets that receive extra data after a response is complete should not be
1990// reused.
1991TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
1992 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1993 MockWrite data_writes1[] = {
1994 MockWrite("HEAD / HTTP/1.1\r\n"
1995 "Host: www.borked.com\r\n"
1996 "Connection: keep-alive\r\n\r\n"),
1997 };
1998
1999 MockRead data_reads1[] = {
2000 MockRead("HTTP/1.1 200 OK\r\n"
2001 "Connection: keep-alive\r\n"
2002 "Content-Length: 22\r\n\r\n"
2003 "This server is borked."),
2004 };
2005
2006 MockWrite data_writes2[] = {
2007 MockWrite("GET /foo HTTP/1.1\r\n"
2008 "Host: www.borked.com\r\n"
2009 "Connection: keep-alive\r\n\r\n"),
2010 };
2011
2012 MockRead data_reads2[] = {
2013 MockRead("HTTP/1.1 200 OK\r\n"
2014 "Content-Length: 3\r\n\r\n"
2015 "foo"),
2016 };
2017 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2018 data_writes1, arraysize(data_writes1));
2019 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2020 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2021 data_writes2, arraysize(data_writes2));
2022 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2023
2024 TestCompletionCallback callback;
2025 HttpRequestInfo request1;
2026 request1.method = "HEAD";
2027 request1.url = GURL("http://www.borked.com/");
2028
2029 std::unique_ptr<HttpTransaction> trans1(
2030 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2031 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2032 EXPECT_EQ(OK, callback.GetResult(rv));
2033
2034 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2035 ASSERT_TRUE(response1);
2036 ASSERT_TRUE(response1->headers);
2037 EXPECT_EQ(200, response1->headers->response_code());
2038 EXPECT_TRUE(response1->headers->IsKeepAlive());
2039
2040 std::string response_data1;
2041 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
2042 EXPECT_EQ("", response_data1);
2043 // Deleting the transaction attempts to release the socket back into the
2044 // socket pool.
2045 trans1.reset();
2046
2047 HttpRequestInfo request2;
2048 request2.method = "GET";
2049 request2.url = GURL("http://www.borked.com/foo");
2050
2051 std::unique_ptr<HttpTransaction> trans2(
2052 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2053 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
2054 EXPECT_EQ(OK, callback.GetResult(rv));
2055
2056 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2057 ASSERT_TRUE(response2);
2058 ASSERT_TRUE(response2->headers);
2059 EXPECT_EQ(200, response2->headers->response_code());
2060
2061 std::string response_data2;
2062 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2));
2063 EXPECT_EQ("foo", response_data2);
2064}
2065
2066TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
2067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2068 MockWrite data_writes1[] = {
2069 MockWrite("GET / HTTP/1.1\r\n"
2070 "Host: www.borked.com\r\n"
2071 "Connection: keep-alive\r\n\r\n"),
2072 };
2073
2074 MockRead data_reads1[] = {
2075 MockRead("HTTP/1.1 200 OK\r\n"
2076 "Connection: keep-alive\r\n"
2077 "Content-Length: 22\r\n\r\n"
2078 "This server is borked."
2079 "Bonus data!"),
2080 };
2081
2082 MockWrite data_writes2[] = {
2083 MockWrite("GET /foo HTTP/1.1\r\n"
2084 "Host: www.borked.com\r\n"
2085 "Connection: keep-alive\r\n\r\n"),
2086 };
2087
2088 MockRead data_reads2[] = {
2089 MockRead("HTTP/1.1 200 OK\r\n"
2090 "Content-Length: 3\r\n\r\n"
2091 "foo"),
2092 };
2093 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2094 data_writes1, arraysize(data_writes1));
2095 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2096 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2097 data_writes2, arraysize(data_writes2));
2098 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2099
2100 TestCompletionCallback callback;
2101 HttpRequestInfo request1;
2102 request1.method = "GET";
2103 request1.url = GURL("http://www.borked.com/");
2104
2105 std::unique_ptr<HttpTransaction> trans1(
2106 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2107 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2108 EXPECT_EQ(OK, callback.GetResult(rv));
2109
2110 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2111 ASSERT_TRUE(response1);
2112 ASSERT_TRUE(response1->headers);
2113 EXPECT_EQ(200, response1->headers->response_code());
2114 EXPECT_TRUE(response1->headers->IsKeepAlive());
2115
2116 std::string response_data1;
2117 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
2118 EXPECT_EQ("This server is borked.", response_data1);
2119 // Deleting the transaction attempts to release the socket back into the
2120 // socket pool.
2121 trans1.reset();
2122
2123 HttpRequestInfo request2;
2124 request2.method = "GET";
2125 request2.url = GURL("http://www.borked.com/foo");
2126
2127 std::unique_ptr<HttpTransaction> trans2(
2128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2129 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
2130 EXPECT_EQ(OK, callback.GetResult(rv));
2131
2132 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2133 ASSERT_TRUE(response2);
2134 ASSERT_TRUE(response2->headers);
2135 EXPECT_EQ(200, response2->headers->response_code());
2136
2137 std::string response_data2;
2138 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2));
2139 EXPECT_EQ("foo", response_data2);
2140}
2141
2142TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
2143 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2144 MockWrite data_writes1[] = {
2145 MockWrite("GET / HTTP/1.1\r\n"
2146 "Host: www.borked.com\r\n"
2147 "Connection: keep-alive\r\n\r\n"),
2148 };
2149
2150 MockRead data_reads1[] = {
2151 MockRead("HTTP/1.1 200 OK\r\n"
2152 "Connection: keep-alive\r\n"
2153 "Transfer-Encoding: chunked\r\n\r\n"),
2154 MockRead("16\r\nThis server is borked.\r\n"),
2155 MockRead("0\r\n\r\nBonus data!"),
2156 };
2157
2158 MockWrite data_writes2[] = {
2159 MockWrite("GET /foo HTTP/1.1\r\n"
2160 "Host: www.borked.com\r\n"
2161 "Connection: keep-alive\r\n\r\n"),
2162 };
2163
2164 MockRead data_reads2[] = {
2165 MockRead("HTTP/1.1 200 OK\r\n"
2166 "Content-Length: 3\r\n\r\n"
2167 "foo"),
2168 };
2169 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2170 data_writes1, arraysize(data_writes1));
2171 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2172 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2173 data_writes2, arraysize(data_writes2));
2174 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2175
2176 TestCompletionCallback callback;
2177 HttpRequestInfo request1;
2178 request1.method = "GET";
2179 request1.url = GURL("http://www.borked.com/");
2180
2181 std::unique_ptr<HttpTransaction> trans1(
2182 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2183 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2184 EXPECT_EQ(OK, callback.GetResult(rv));
2185
2186 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2187 ASSERT_TRUE(response1);
2188 ASSERT_TRUE(response1->headers);
2189 EXPECT_EQ(200, response1->headers->response_code());
2190 EXPECT_TRUE(response1->headers->IsKeepAlive());
2191
2192 std::string response_data1;
2193 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
2194 EXPECT_EQ("This server is borked.", response_data1);
2195 // Deleting the transaction attempts to release the socket back into the
2196 // socket pool.
2197 trans1.reset();
2198
2199 HttpRequestInfo request2;
2200 request2.method = "GET";
2201 request2.url = GURL("http://www.borked.com/foo");
2202
2203 std::unique_ptr<HttpTransaction> trans2(
2204 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2205 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
2206 EXPECT_EQ(OK, callback.GetResult(rv));
2207
2208 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2209 ASSERT_TRUE(response2);
2210 ASSERT_TRUE(response2->headers);
2211 EXPECT_EQ(200, response2->headers->response_code());
2212
2213 std::string response_data2;
2214 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2));
2215 EXPECT_EQ("foo", response_data2);
2216}
2217
2218// This is a little different from the others - it tests the case that the
2219// HttpStreamParser doesn't know if there's extra data on a socket or not when
2220// the HttpNetworkTransaction is torn down, because the response body hasn't
2221// been read from yet, but the request goes through the HttpResponseBodyDrainer.
2222TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
2223 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2224 MockWrite data_writes1[] = {
2225 MockWrite("GET / HTTP/1.1\r\n"
2226 "Host: www.borked.com\r\n"
2227 "Connection: keep-alive\r\n\r\n"),
2228 };
2229
2230 MockRead data_reads1[] = {
2231 MockRead("HTTP/1.1 200 OK\r\n"
2232 "Connection: keep-alive\r\n"
2233 "Transfer-Encoding: chunked\r\n\r\n"),
2234 MockRead("16\r\nThis server is borked.\r\n"),
2235 MockRead("0\r\n\r\nBonus data!"),
2236 };
2237 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2238 data_writes1, arraysize(data_writes1));
2239 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2240
2241 TestCompletionCallback callback;
2242 HttpRequestInfo request1;
2243 request1.method = "GET";
2244 request1.url = GURL("http://www.borked.com/");
2245
2246 std::unique_ptr<HttpTransaction> trans1(
2247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2248 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2249 EXPECT_EQ(OK, callback.GetResult(rv));
2250
2251 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2252 ASSERT_TRUE(response1);
2253 ASSERT_TRUE(response1->headers);
2254 EXPECT_EQ(200, response1->headers->response_code());
2255 EXPECT_TRUE(response1->headers->IsKeepAlive());
2256
2257 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2258 // response body.
2259 trans1.reset();
2260
2261 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2262 // socket can't be reused, rather than returning it to the socket pool.
2263 base::RunLoop().RunUntilIdle();
2264
2265 // There should be no idle sockets in the pool.
2266 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2267}
2268
[email protected]038e9a32008-10-08 22:40:162269// Test the request-challenge-retry sequence for basic auth.
2270// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:022271TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422272 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162273 request.method = "GET";
bncce36dca22015-04-21 22:11:232274 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162275 request.load_flags = 0;
2276
vishal.b62985ca92015-04-17 08:45:512277 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072278 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092279 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2280 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412281 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272282
[email protected]f9ee6b52008-11-08 06:46:232283 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232284 MockWrite(
2285 "GET / HTTP/1.1\r\n"
2286 "Host: www.example.org\r\n"
2287 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232288 };
2289
[email protected]038e9a32008-10-08 22:40:162290 MockRead data_reads1[] = {
2291 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2292 // Give a couple authenticate options (only the middle one is actually
2293 // supported).
[email protected]22927ad2009-09-21 19:56:192294 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162295 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2296 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2297 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2298 // Large content-length -- won't matter, as connection will be reset.
2299 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062300 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162301 };
2302
2303 // After calling trans->RestartWithAuth(), this is the request we should
2304 // be issuing -- the final header line contains the credentials.
2305 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232306 MockWrite(
2307 "GET / HTTP/1.1\r\n"
2308 "Host: www.example.org\r\n"
2309 "Connection: keep-alive\r\n"
2310 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162311 };
2312
2313 // Lastly, the server responds with the actual content.
2314 MockRead data_reads2[] = {
2315 MockRead("HTTP/1.0 200 OK\r\n"),
2316 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2317 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062318 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162319 };
2320
[email protected]31a2bfe2010-02-09 08:03:392321 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2322 data_writes1, arraysize(data_writes1));
2323 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2324 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2326 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162327
[email protected]49639fa2011-12-20 23:22:412328 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162329
[email protected]49639fa2011-12-20 23:22:412330 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422331 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162332
2333 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422334 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162335
[email protected]58e32bb2013-01-21 18:23:252336 LoadTimingInfo load_timing_info1;
2337 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2338 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2339
sclittlefb249892015-09-10 21:33:222340 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2341 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2342 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:192343 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2344
[email protected]1c773ea12009-04-28 19:58:422345 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522346 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042347 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162348
[email protected]49639fa2011-12-20 23:22:412349 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162350
[email protected]49639fa2011-12-20 23:22:412351 rv = trans->RestartWithAuth(
2352 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422353 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162354
2355 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422356 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162357
[email protected]58e32bb2013-01-21 18:23:252358 LoadTimingInfo load_timing_info2;
2359 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2360 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2361 // The load timing after restart should have a new socket ID, and times after
2362 // those of the first load timing.
2363 EXPECT_LE(load_timing_info1.receive_headers_end,
2364 load_timing_info2.connect_timing.connect_start);
2365 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2366
sclittlefb249892015-09-10 21:33:222367 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2368 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2369 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
[email protected]b8015c42013-12-24 15:18:192370 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2371
[email protected]038e9a32008-10-08 22:40:162372 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522373 ASSERT_TRUE(response);
2374 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162375 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162376}
2377
ttuttled9dbc652015-09-29 20:00:592378// Test the request-challenge-retry sequence for basic auth.
2379// (basic auth is the easiest to mock, because it has no randomness).
2380TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
2381 HttpRequestInfo request;
2382 request.method = "GET";
2383 request.url = GURL("http://www.example.org/");
2384 request.load_flags = 0;
2385
2386 TestNetLog log;
2387 MockHostResolver* resolver = new MockHostResolver();
2388 session_deps_.net_log = &log;
2389 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092390 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
2391 std::unique_ptr<HttpTransaction> trans(
ttuttled9dbc652015-09-29 20:00:592392 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2393
2394 resolver->rules()->ClearRules();
2395 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2396
2397 MockWrite data_writes1[] = {
2398 MockWrite("GET / HTTP/1.1\r\n"
2399 "Host: www.example.org\r\n"
2400 "Connection: keep-alive\r\n\r\n"),
2401 };
2402
2403 MockRead data_reads1[] = {
2404 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2405 // Give a couple authenticate options (only the middle one is actually
2406 // supported).
2407 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2408 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2409 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2410 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2411 // Large content-length -- won't matter, as connection will be reset.
2412 MockRead("Content-Length: 10000\r\n\r\n"),
2413 MockRead(SYNCHRONOUS, ERR_FAILED),
2414 };
2415
2416 // After calling trans->RestartWithAuth(), this is the request we should
2417 // be issuing -- the final header line contains the credentials.
2418 MockWrite data_writes2[] = {
2419 MockWrite("GET / HTTP/1.1\r\n"
2420 "Host: www.example.org\r\n"
2421 "Connection: keep-alive\r\n"
2422 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2423 };
2424
2425 // Lastly, the server responds with the actual content.
2426 MockRead data_reads2[] = {
2427 MockRead("HTTP/1.0 200 OK\r\n"),
2428 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2429 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2430 };
2431
2432 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2433 data_writes1, arraysize(data_writes1));
2434 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2435 data_writes2, arraysize(data_writes2));
2436 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2437 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2438
2439 TestCompletionCallback callback1;
2440
2441 EXPECT_EQ(OK, callback1.GetResult(trans->Start(&request, callback1.callback(),
2442 BoundNetLog())));
2443
2444 LoadTimingInfo load_timing_info1;
2445 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2446 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2447
2448 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2449 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2450 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
2451 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2452
2453 const HttpResponseInfo* response = trans->GetResponseInfo();
2454 ASSERT_TRUE(response);
2455 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2456
2457 IPEndPoint endpoint;
2458 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2459 ASSERT_FALSE(endpoint.address().empty());
2460 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2461
2462 resolver->rules()->ClearRules();
2463 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2464
2465 TestCompletionCallback callback2;
2466
2467 EXPECT_EQ(OK, callback2.GetResult(trans->RestartWithAuth(
2468 AuthCredentials(kFoo, kBar), callback2.callback())));
2469
2470 LoadTimingInfo load_timing_info2;
2471 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2472 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2473 // The load timing after restart should have a new socket ID, and times after
2474 // those of the first load timing.
2475 EXPECT_LE(load_timing_info1.receive_headers_end,
2476 load_timing_info2.connect_timing.connect_start);
2477 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2478
2479 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2480 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2481 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
2482 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2483
2484 response = trans->GetResponseInfo();
2485 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522486 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592487 EXPECT_EQ(100, response->headers->GetContentLength());
2488
2489 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2490 ASSERT_FALSE(endpoint.address().empty());
2491 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2492}
2493
[email protected]23e482282013-06-14 16:08:022494TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462495 HttpRequestInfo request;
2496 request.method = "GET";
bncce36dca22015-04-21 22:11:232497 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292498 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462499
danakj1fd259a02016-04-16 03:17:092500 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2501 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412502 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272503
[email protected]861fcd52009-08-26 02:33:462504 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232505 MockWrite(
2506 "GET / HTTP/1.1\r\n"
2507 "Host: www.example.org\r\n"
2508 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462509 };
2510
2511 MockRead data_reads[] = {
2512 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2513 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2514 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2515 // Large content-length -- won't matter, as connection will be reset.
2516 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062517 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462518 };
2519
[email protected]31a2bfe2010-02-09 08:03:392520 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2521 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072522 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412523 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462524
[email protected]49639fa2011-12-20 23:22:412525 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462526 EXPECT_EQ(ERR_IO_PENDING, rv);
2527
2528 rv = callback.WaitForResult();
2529 EXPECT_EQ(0, rv);
2530
sclittlefb249892015-09-10 21:33:222531 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2532 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2533 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
[email protected]b8015c42013-12-24 15:18:192534 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2535
[email protected]861fcd52009-08-26 02:33:462536 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522537 ASSERT_TRUE(response);
2538 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462539}
2540
[email protected]2d2697f92009-02-18 21:00:322541// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2542// connection.
[email protected]23e482282013-06-14 16:08:022543TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182544 // On the second pass, the body read of the auth challenge is synchronous, so
2545 // IsConnectedAndIdle returns false. The socket should still be drained and
2546 // reused. See http://crbug.com/544255.
2547 for (int i = 0; i < 2; ++i) {
2548 HttpRequestInfo request;
2549 request.method = "GET";
2550 request.url = GURL("http://www.example.org/");
2551 request.load_flags = 0;
[email protected]2d2697f92009-02-18 21:00:322552
mmenkecc2298e2015-12-07 18:20:182553 TestNetLog log;
2554 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092555 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272556
mmenkecc2298e2015-12-07 18:20:182557 MockWrite data_writes[] = {
2558 MockWrite(ASYNC, 0,
2559 "GET / HTTP/1.1\r\n"
2560 "Host: www.example.org\r\n"
2561 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322562
mmenkecc2298e2015-12-07 18:20:182563 // After calling trans->RestartWithAuth(), this is the request we should
2564 // be issuing -- the final header line contains the credentials.
2565 MockWrite(ASYNC, 6,
2566 "GET / HTTP/1.1\r\n"
2567 "Host: www.example.org\r\n"
2568 "Connection: keep-alive\r\n"
2569 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2570 };
[email protected]2d2697f92009-02-18 21:00:322571
mmenkecc2298e2015-12-07 18:20:182572 MockRead data_reads[] = {
2573 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2574 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2575 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2576 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2577 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322578
mmenkecc2298e2015-12-07 18:20:182579 // Lastly, the server responds with the actual content.
2580 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2581 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2582 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2583 MockRead(ASYNC, 10, "Hello"),
2584 };
[email protected]2d2697f92009-02-18 21:00:322585
mmenkecc2298e2015-12-07 18:20:182586 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2587 arraysize(data_writes));
2588 data.set_busy_before_sync_reads(true);
2589 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462590
mmenkecc2298e2015-12-07 18:20:182591 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322592
danakj1fd259a02016-04-16 03:17:092593 std::unique_ptr<HttpTransaction> trans(
mmenkecc2298e2015-12-07 18:20:182594 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2595 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2596 ASSERT_EQ(OK, callback1.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:322597
mmenkecc2298e2015-12-07 18:20:182598 LoadTimingInfo load_timing_info1;
2599 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2600 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322601
mmenkecc2298e2015-12-07 18:20:182602 const HttpResponseInfo* response = trans->GetResponseInfo();
2603 ASSERT_TRUE(response);
2604 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322605
mmenkecc2298e2015-12-07 18:20:182606 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252607
mmenkecc2298e2015-12-07 18:20:182608 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
2609 callback2.callback());
2610 ASSERT_EQ(OK, callback2.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:322611
mmenkecc2298e2015-12-07 18:20:182612 LoadTimingInfo load_timing_info2;
2613 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2614 TestLoadTimingReused(load_timing_info2);
2615 // The load timing after restart should have the same socket ID, and times
2616 // those of the first load timing.
2617 EXPECT_LE(load_timing_info1.receive_headers_end,
2618 load_timing_info2.send_start);
2619 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322620
mmenkecc2298e2015-12-07 18:20:182621 response = trans->GetResponseInfo();
2622 ASSERT_TRUE(response);
2623 EXPECT_FALSE(response->auth_challenge);
2624 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322625
mmenkecc2298e2015-12-07 18:20:182626 std::string response_data;
2627 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]2d2697f92009-02-18 21:00:322628
mmenkecc2298e2015-12-07 18:20:182629 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2630 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2631 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
2632 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2633 }
[email protected]2d2697f92009-02-18 21:00:322634}
2635
2636// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2637// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022638TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422639 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322640 request.method = "GET";
bncce36dca22015-04-21 22:11:232641 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322642 request.load_flags = 0;
2643
danakj1fd259a02016-04-16 03:17:092644 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272645
[email protected]2d2697f92009-02-18 21:00:322646 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232647 MockWrite(
2648 "GET / HTTP/1.1\r\n"
2649 "Host: www.example.org\r\n"
2650 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322651
bncce36dca22015-04-21 22:11:232652 // After calling trans->RestartWithAuth(), this is the request we should
2653 // be issuing -- the final header line contains the credentials.
2654 MockWrite(
2655 "GET / HTTP/1.1\r\n"
2656 "Host: www.example.org\r\n"
2657 "Connection: keep-alive\r\n"
2658 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322659 };
2660
[email protected]2d2697f92009-02-18 21:00:322661 MockRead data_reads1[] = {
2662 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2663 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312664 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322665
2666 // Lastly, the server responds with the actual content.
2667 MockRead("HTTP/1.1 200 OK\r\n"),
2668 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502669 MockRead("Content-Length: 5\r\n\r\n"),
2670 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322671 };
2672
[email protected]2d0a4f92011-05-05 16:38:462673 // An incorrect reconnect would cause this to be read.
2674 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062675 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462676 };
2677
[email protected]31a2bfe2010-02-09 08:03:392678 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2679 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462680 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2681 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072682 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2683 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322684
[email protected]49639fa2011-12-20 23:22:412685 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322686
danakj1fd259a02016-04-16 03:17:092687 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502688 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412689 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422690 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322691
2692 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422693 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322694
[email protected]1c773ea12009-04-28 19:58:422695 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522696 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042697 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322698
[email protected]49639fa2011-12-20 23:22:412699 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322700
[email protected]49639fa2011-12-20 23:22:412701 rv = trans->RestartWithAuth(
2702 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422703 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322704
2705 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422706 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322707
2708 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522709 ASSERT_TRUE(response);
2710 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502711 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322712}
2713
2714// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2715// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022716TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422717 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322718 request.method = "GET";
bncce36dca22015-04-21 22:11:232719 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322720 request.load_flags = 0;
2721
danakj1fd259a02016-04-16 03:17:092722 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272723
[email protected]2d2697f92009-02-18 21:00:322724 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232725 MockWrite(
2726 "GET / HTTP/1.1\r\n"
2727 "Host: www.example.org\r\n"
2728 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322729
bncce36dca22015-04-21 22:11:232730 // After calling trans->RestartWithAuth(), this is the request we should
2731 // be issuing -- the final header line contains the credentials.
2732 MockWrite(
2733 "GET / HTTP/1.1\r\n"
2734 "Host: www.example.org\r\n"
2735 "Connection: keep-alive\r\n"
2736 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322737 };
2738
2739 // Respond with 5 kb of response body.
2740 std::string large_body_string("Unauthorized");
2741 large_body_string.append(5 * 1024, ' ');
2742 large_body_string.append("\r\n");
2743
2744 MockRead data_reads1[] = {
2745 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2746 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2747 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2748 // 5134 = 12 + 5 * 1024 + 2
2749 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062750 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322751
2752 // Lastly, the server responds with the actual content.
2753 MockRead("HTTP/1.1 200 OK\r\n"),
2754 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502755 MockRead("Content-Length: 5\r\n\r\n"),
2756 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322757 };
2758
[email protected]2d0a4f92011-05-05 16:38:462759 // An incorrect reconnect would cause this to be read.
2760 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062761 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462762 };
2763
[email protected]31a2bfe2010-02-09 08:03:392764 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2765 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462766 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2767 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072768 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2769 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322770
[email protected]49639fa2011-12-20 23:22:412771 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322772
danakj1fd259a02016-04-16 03:17:092773 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502774 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412775 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422776 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322777
2778 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422779 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322780
[email protected]1c773ea12009-04-28 19:58:422781 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522782 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042783 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322784
[email protected]49639fa2011-12-20 23:22:412785 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322786
[email protected]49639fa2011-12-20 23:22:412787 rv = trans->RestartWithAuth(
2788 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422789 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322790
2791 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422792 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322793
2794 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522795 ASSERT_TRUE(response);
2796 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502797 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322798}
2799
2800// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312801// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022802TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312803 HttpRequestInfo request;
2804 request.method = "GET";
bncce36dca22015-04-21 22:11:232805 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312806 request.load_flags = 0;
2807
danakj1fd259a02016-04-16 03:17:092808 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272809
[email protected]11203f012009-11-12 23:02:312810 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232811 MockWrite(
2812 "GET / HTTP/1.1\r\n"
2813 "Host: www.example.org\r\n"
2814 "Connection: keep-alive\r\n\r\n"),
2815 // This simulates the seemingly successful write to a closed connection
2816 // if the bug is not fixed.
2817 MockWrite(
2818 "GET / HTTP/1.1\r\n"
2819 "Host: www.example.org\r\n"
2820 "Connection: keep-alive\r\n"
2821 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312822 };
2823
2824 MockRead data_reads1[] = {
2825 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2826 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2827 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2828 MockRead("Content-Length: 14\r\n\r\n"),
2829 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062830 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312831 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062832 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312833 };
2834
2835 // After calling trans->RestartWithAuth(), this is the request we should
2836 // be issuing -- the final header line contains the credentials.
2837 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232838 MockWrite(
2839 "GET / HTTP/1.1\r\n"
2840 "Host: www.example.org\r\n"
2841 "Connection: keep-alive\r\n"
2842 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312843 };
2844
2845 // Lastly, the server responds with the actual content.
2846 MockRead data_reads2[] = {
2847 MockRead("HTTP/1.1 200 OK\r\n"),
2848 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502849 MockRead("Content-Length: 5\r\n\r\n"),
2850 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312851 };
2852
[email protected]31a2bfe2010-02-09 08:03:392853 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2854 data_writes1, arraysize(data_writes1));
2855 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2856 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072857 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2858 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312859
[email protected]49639fa2011-12-20 23:22:412860 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312861
danakj1fd259a02016-04-16 03:17:092862 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502863 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412864 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312865 EXPECT_EQ(ERR_IO_PENDING, rv);
2866
2867 rv = callback1.WaitForResult();
2868 EXPECT_EQ(OK, rv);
2869
2870 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522871 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042872 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312873
[email protected]49639fa2011-12-20 23:22:412874 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312875
[email protected]49639fa2011-12-20 23:22:412876 rv = trans->RestartWithAuth(
2877 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312878 EXPECT_EQ(ERR_IO_PENDING, rv);
2879
2880 rv = callback2.WaitForResult();
2881 EXPECT_EQ(OK, rv);
2882
2883 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522884 ASSERT_TRUE(response);
2885 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502886 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312887}
2888
[email protected]394816e92010-08-03 07:38:592889// Test the request-challenge-retry sequence for basic auth, over a connection
2890// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012891TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2892 HttpRequestInfo request;
2893 request.method = "GET";
bncce36dca22015-04-21 22:11:232894 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012895 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292896 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012897
2898 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032899 session_deps_.proxy_service =
2900 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512901 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012902 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092903 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012904
2905 // Since we have proxy, should try to establish tunnel.
2906 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542907 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172908 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542909 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012910 };
2911
mmenkee71e15332015-10-07 16:39:542912 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012913 // connection.
2914 MockRead data_reads1[] = {
2915 // No credentials.
2916 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2917 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542918 };
ttuttle34f63b52015-03-05 04:33:012919
mmenkee71e15332015-10-07 16:39:542920 // Since the first connection couldn't be reused, need to establish another
2921 // once given credentials.
2922 MockWrite data_writes2[] = {
2923 // After calling trans->RestartWithAuth(), this is the request we should
2924 // be issuing -- the final header line contains the credentials.
2925 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172926 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542927 "Proxy-Connection: keep-alive\r\n"
2928 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2929
2930 MockWrite("GET / HTTP/1.1\r\n"
2931 "Host: www.example.org\r\n"
2932 "Connection: keep-alive\r\n\r\n"),
2933 };
2934
2935 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012936 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2937
2938 MockRead("HTTP/1.1 200 OK\r\n"),
2939 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2940 MockRead("Content-Length: 5\r\n\r\n"),
2941 MockRead(SYNCHRONOUS, "hello"),
2942 };
2943
2944 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2945 data_writes1, arraysize(data_writes1));
2946 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542947 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2948 data_writes2, arraysize(data_writes2));
2949 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012950 SSLSocketDataProvider ssl(ASYNC, OK);
2951 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2952
2953 TestCompletionCallback callback1;
2954
danakj1fd259a02016-04-16 03:17:092955 std::unique_ptr<HttpTransaction> trans(
ttuttle34f63b52015-03-05 04:33:012956 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2957
2958 int rv = trans->Start(&request, callback1.callback(), log.bound());
2959 EXPECT_EQ(ERR_IO_PENDING, rv);
2960
2961 rv = callback1.WaitForResult();
2962 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462963 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012964 log.GetEntries(&entries);
2965 size_t pos = ExpectLogContainsSomewhere(
2966 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2967 NetLog::PHASE_NONE);
2968 ExpectLogContainsSomewhere(
2969 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2970 NetLog::PHASE_NONE);
2971
2972 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522973 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012974 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522975 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012976 EXPECT_EQ(407, response->headers->response_code());
2977 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2978 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2979
2980 LoadTimingInfo load_timing_info;
2981 // CONNECT requests and responses are handled at the connect job level, so
2982 // the transaction does not yet have a connection.
2983 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2984
2985 TestCompletionCallback callback2;
2986
2987 rv =
2988 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2989 EXPECT_EQ(ERR_IO_PENDING, rv);
2990
2991 rv = callback2.WaitForResult();
2992 EXPECT_EQ(OK, rv);
2993
2994 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522995 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012996
2997 EXPECT_TRUE(response->headers->IsKeepAlive());
2998 EXPECT_EQ(200, response->headers->response_code());
2999 EXPECT_EQ(5, response->headers->GetContentLength());
3000 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3001
3002 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523003 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013004
3005 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3006 TestLoadTimingNotReusedWithPac(load_timing_info,
3007 CONNECT_TIMING_HAS_SSL_TIMES);
3008
3009 trans.reset();
3010 session->CloseAllConnections();
3011}
3012
3013// Test the request-challenge-retry sequence for basic auth, over a connection
3014// that requires a restart when setting up an SSL tunnel.
3015TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593016 HttpRequestInfo request;
3017 request.method = "GET";
bncce36dca22015-04-21 22:11:233018 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593019 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293020 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593021
[email protected]cb9bf6ca2011-01-28 13:15:273022 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033023 session_deps_.proxy_service =
3024 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513025 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073026 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273028
[email protected]394816e92010-08-03 07:38:593029 // Since we have proxy, should try to establish tunnel.
3030 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543031 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173032 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543033 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113034 };
3035
mmenkee71e15332015-10-07 16:39:543036 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083037 // connection.
3038 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543039 // No credentials.
3040 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3041 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3042 MockRead("Proxy-Connection: close\r\n\r\n"),
3043 };
mmenkee0b5c882015-08-26 20:29:113044
mmenkee71e15332015-10-07 16:39:543045 MockWrite data_writes2[] = {
3046 // After calling trans->RestartWithAuth(), this is the request we should
3047 // be issuing -- the final header line contains the credentials.
3048 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173049 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543050 "Proxy-Connection: keep-alive\r\n"
3051 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083052
mmenkee71e15332015-10-07 16:39:543053 MockWrite("GET / HTTP/1.1\r\n"
3054 "Host: www.example.org\r\n"
3055 "Connection: keep-alive\r\n\r\n"),
3056 };
3057
3058 MockRead data_reads2[] = {
3059 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3060
3061 MockRead("HTTP/1.1 200 OK\r\n"),
3062 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3063 MockRead("Content-Length: 5\r\n\r\n"),
3064 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593065 };
3066
3067 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3068 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073069 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543070 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3071 data_writes2, arraysize(data_writes2));
3072 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063073 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593075
[email protected]49639fa2011-12-20 23:22:413076 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593077
danakj1fd259a02016-04-16 03:17:093078 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503080
[email protected]49639fa2011-12-20 23:22:413081 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:593082 EXPECT_EQ(ERR_IO_PENDING, rv);
3083
3084 rv = callback1.WaitForResult();
3085 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:463086 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403087 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593088 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403089 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:593090 NetLog::PHASE_NONE);
3091 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403092 entries, pos,
[email protected]394816e92010-08-03 07:38:593093 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3094 NetLog::PHASE_NONE);
3095
3096 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523097 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013098 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523099 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593100 EXPECT_EQ(407, response->headers->response_code());
3101 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043102 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593103
[email protected]029c83b62013-01-24 05:28:203104 LoadTimingInfo load_timing_info;
3105 // CONNECT requests and responses are handled at the connect job level, so
3106 // the transaction does not yet have a connection.
3107 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3108
[email protected]49639fa2011-12-20 23:22:413109 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593110
[email protected]49639fa2011-12-20 23:22:413111 rv = trans->RestartWithAuth(
3112 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:593113 EXPECT_EQ(ERR_IO_PENDING, rv);
3114
3115 rv = callback2.WaitForResult();
3116 EXPECT_EQ(OK, rv);
3117
3118 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523119 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593120
3121 EXPECT_TRUE(response->headers->IsKeepAlive());
3122 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503123 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593124 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3125
3126 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523127 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503128
[email protected]029c83b62013-01-24 05:28:203129 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3130 TestLoadTimingNotReusedWithPac(load_timing_info,
3131 CONNECT_TIMING_HAS_SSL_TIMES);
3132
[email protected]0b0bf032010-09-21 18:08:503133 trans.reset();
[email protected]102e27c2011-02-23 01:01:313134 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593135}
3136
[email protected]11203f012009-11-12 23:02:313137// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013138// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
3139TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233140 // On the second pass, the body read of the auth challenge is synchronous, so
3141 // IsConnectedAndIdle returns false. The socket should still be drained and
3142 // reused. See http://crbug.com/544255.
3143 for (int i = 0; i < 2; ++i) {
3144 HttpRequestInfo request;
3145 request.method = "GET";
3146 request.url = GURL("https://www.example.org/");
3147 // Ensure that proxy authentication is attempted even
3148 // when the no authentication data flag is set.
3149 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013150
mmenked39192ee2015-12-09 00:57:233151 // Configure against proxy server "myproxy:70".
3152 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3153 BoundTestNetLog log;
3154 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093155 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013156
danakj1fd259a02016-04-16 03:17:093157 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:233158 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ttuttle34f63b52015-03-05 04:33:013159
mmenked39192ee2015-12-09 00:57:233160 // Since we have proxy, should try to establish tunnel.
3161 MockWrite data_writes1[] = {
3162 MockWrite(ASYNC, 0,
3163 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3164 "Host: www.example.org:443\r\n"
3165 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013166
mmenked39192ee2015-12-09 00:57:233167 // After calling trans->RestartWithAuth(), this is the request we should
3168 // be issuing -- the final header line contains the credentials.
3169 MockWrite(ASYNC, 3,
3170 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3171 "Host: www.example.org:443\r\n"
3172 "Proxy-Connection: keep-alive\r\n"
3173 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3174 };
ttuttle34f63b52015-03-05 04:33:013175
mmenked39192ee2015-12-09 00:57:233176 // The proxy responds to the connect with a 407, using a persistent
3177 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3178 MockRead data_reads1[] = {
3179 // No credentials.
3180 MockRead(ASYNC, 1,
3181 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3182 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3183 "Proxy-Connection: keep-alive\r\n"
3184 "Content-Length: 10\r\n\r\n"),
3185 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013186
mmenked39192ee2015-12-09 00:57:233187 // Wrong credentials (wrong password).
3188 MockRead(ASYNC, 4,
3189 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3190 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3191 "Proxy-Connection: keep-alive\r\n"
3192 "Content-Length: 10\r\n\r\n"),
3193 // No response body because the test stops reading here.
3194 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3195 };
ttuttle34f63b52015-03-05 04:33:013196
mmenked39192ee2015-12-09 00:57:233197 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3198 arraysize(data_writes1));
3199 data1.set_busy_before_sync_reads(true);
3200 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013201
mmenked39192ee2015-12-09 00:57:233202 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013203
mmenked39192ee2015-12-09 00:57:233204 int rv = trans->Start(&request, callback1.callback(), log.bound());
3205 EXPECT_EQ(OK, callback1.GetResult(rv));
ttuttle34f63b52015-03-05 04:33:013206
mmenked39192ee2015-12-09 00:57:233207 TestNetLogEntry::List entries;
3208 log.GetEntries(&entries);
3209 size_t pos = ExpectLogContainsSomewhere(
3210 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3211 NetLog::PHASE_NONE);
3212 ExpectLogContainsSomewhere(
3213 entries, pos,
3214 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3215 NetLog::PHASE_NONE);
ttuttle34f63b52015-03-05 04:33:013216
mmenked39192ee2015-12-09 00:57:233217 const HttpResponseInfo* response = trans->GetResponseInfo();
3218 ASSERT_TRUE(response);
3219 ASSERT_TRUE(response->headers);
3220 EXPECT_TRUE(response->headers->IsKeepAlive());
3221 EXPECT_EQ(407, response->headers->response_code());
3222 EXPECT_EQ(10, response->headers->GetContentLength());
3223 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3224 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013225
mmenked39192ee2015-12-09 00:57:233226 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013227
mmenked39192ee2015-12-09 00:57:233228 // Wrong password (should be "bar").
3229 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
3230 callback2.callback());
3231 EXPECT_EQ(OK, callback2.GetResult(rv));
ttuttle34f63b52015-03-05 04:33:013232
mmenked39192ee2015-12-09 00:57:233233 response = trans->GetResponseInfo();
3234 ASSERT_TRUE(response);
3235 ASSERT_TRUE(response->headers);
3236 EXPECT_TRUE(response->headers->IsKeepAlive());
3237 EXPECT_EQ(407, response->headers->response_code());
3238 EXPECT_EQ(10, response->headers->GetContentLength());
3239 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3240 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013241
mmenked39192ee2015-12-09 00:57:233242 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3243 // out of scope.
3244 session->CloseAllConnections();
3245 }
ttuttle34f63b52015-03-05 04:33:013246}
3247
3248// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3249// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
3250TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233251 // On the second pass, the body read of the auth challenge is synchronous, so
3252 // IsConnectedAndIdle returns false. The socket should still be drained and
3253 // reused. See http://crbug.com/544255.
3254 for (int i = 0; i < 2; ++i) {
3255 HttpRequestInfo request;
3256 request.method = "GET";
3257 request.url = GURL("https://www.example.org/");
3258 // Ensure that proxy authentication is attempted even
3259 // when the no authentication data flag is set.
3260 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3261
3262 // Configure against proxy server "myproxy:70".
3263 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3264 BoundTestNetLog log;
3265 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093266 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233267
danakj1fd259a02016-04-16 03:17:093268 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:233269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3270
3271 // Since we have proxy, should try to establish tunnel.
3272 MockWrite data_writes1[] = {
3273 MockWrite(ASYNC, 0,
3274 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3275 "Host: www.example.org:443\r\n"
3276 "Proxy-Connection: keep-alive\r\n\r\n"),
3277
3278 // After calling trans->RestartWithAuth(), this is the request we should
3279 // be issuing -- the final header line contains the credentials.
3280 MockWrite(ASYNC, 3,
3281 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3282 "Host: www.example.org:443\r\n"
3283 "Proxy-Connection: keep-alive\r\n"
3284 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3285 };
3286
3287 // The proxy responds to the connect with a 407, using a persistent
3288 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3289 MockRead data_reads1[] = {
3290 // No credentials.
3291 MockRead(ASYNC, 1,
3292 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3293 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3294 "Content-Length: 10\r\n\r\n"),
3295 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3296
3297 // Wrong credentials (wrong password).
3298 MockRead(ASYNC, 4,
3299 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3300 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3301 "Content-Length: 10\r\n\r\n"),
3302 // No response body because the test stops reading here.
3303 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3304 };
3305
3306 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3307 arraysize(data_writes1));
3308 data1.set_busy_before_sync_reads(true);
3309 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3310
3311 TestCompletionCallback callback1;
3312
3313 int rv = trans->Start(&request, callback1.callback(), log.bound());
3314 EXPECT_EQ(OK, callback1.GetResult(rv));
3315
3316 TestNetLogEntry::List entries;
3317 log.GetEntries(&entries);
3318 size_t pos = ExpectLogContainsSomewhere(
3319 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3320 NetLog::PHASE_NONE);
3321 ExpectLogContainsSomewhere(
3322 entries, pos,
3323 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3324 NetLog::PHASE_NONE);
3325
3326 const HttpResponseInfo* response = trans->GetResponseInfo();
3327 ASSERT_TRUE(response);
3328 ASSERT_TRUE(response->headers);
3329 EXPECT_TRUE(response->headers->IsKeepAlive());
3330 EXPECT_EQ(407, response->headers->response_code());
3331 EXPECT_EQ(10, response->headers->GetContentLength());
3332 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3333 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3334
3335 TestCompletionCallback callback2;
3336
3337 // Wrong password (should be "bar").
3338 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
3339 callback2.callback());
3340 EXPECT_EQ(OK, callback2.GetResult(rv));
3341
3342 response = trans->GetResponseInfo();
3343 ASSERT_TRUE(response);
3344 ASSERT_TRUE(response->headers);
3345 EXPECT_TRUE(response->headers->IsKeepAlive());
3346 EXPECT_EQ(407, response->headers->response_code());
3347 EXPECT_EQ(10, response->headers->GetContentLength());
3348 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3349 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3350
3351 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3352 // out of scope.
3353 session->CloseAllConnections();
3354 }
3355}
3356
3357// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3358// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3359// the case the server sends extra data on the original socket, so it can't be
3360// reused.
3361TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273362 HttpRequestInfo request;
3363 request.method = "GET";
bncce36dca22015-04-21 22:11:233364 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273365 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293366 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273367
[email protected]2d2697f92009-02-18 21:00:323368 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233369 session_deps_.proxy_service =
3370 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513371 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073372 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323374
[email protected]2d2697f92009-02-18 21:00:323375 // Since we have proxy, should try to establish tunnel.
3376 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233377 MockWrite(ASYNC, 0,
3378 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173379 "Host: www.example.org:443\r\n"
3380 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233381 };
[email protected]2d2697f92009-02-18 21:00:323382
mmenked39192ee2015-12-09 00:57:233383 // The proxy responds to the connect with a 407, using a persistent, but sends
3384 // extra data, so the socket cannot be reused.
3385 MockRead data_reads1[] = {
3386 // No credentials.
3387 MockRead(ASYNC, 1,
3388 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3389 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3390 "Content-Length: 10\r\n\r\n"),
3391 MockRead(SYNCHRONOUS, 2, "0123456789"),
3392 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3393 };
3394
3395 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233396 // After calling trans->RestartWithAuth(), this is the request we should
3397 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233398 MockWrite(ASYNC, 0,
3399 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173400 "Host: www.example.org:443\r\n"
3401 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233402 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3403
3404 MockWrite(ASYNC, 2,
3405 "GET / HTTP/1.1\r\n"
3406 "Host: www.example.org\r\n"
3407 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323408 };
3409
mmenked39192ee2015-12-09 00:57:233410 MockRead data_reads2[] = {
3411 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323412
mmenked39192ee2015-12-09 00:57:233413 MockRead(ASYNC, 3,
3414 "HTTP/1.1 200 OK\r\n"
3415 "Content-Type: text/html; charset=iso-8859-1\r\n"
3416 "Content-Length: 5\r\n\r\n"),
3417 // No response body because the test stops reading here.
3418 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323419 };
3420
mmenked39192ee2015-12-09 00:57:233421 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3422 arraysize(data_writes1));
3423 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073424 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233425 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3426 arraysize(data_writes2));
3427 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3428 SSLSocketDataProvider ssl(ASYNC, OK);
3429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323430
[email protected]49639fa2011-12-20 23:22:413431 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323432
danakj1fd259a02016-04-16 03:17:093433 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:233434 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:323435
mmenked39192ee2015-12-09 00:57:233436 int rv = trans->Start(&request, callback1.callback(), log.bound());
3437 EXPECT_EQ(OK, callback1.GetResult(rv));
3438
mmenke43758e62015-05-04 21:09:463439 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403440 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393441 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403442 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:393443 NetLog::PHASE_NONE);
3444 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403445 entries, pos,
[email protected]dbb83db2010-05-11 18:13:393446 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3447 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:323448
[email protected]1c773ea12009-04-28 19:58:423449 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243450 ASSERT_TRUE(response);
3451 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323452 EXPECT_TRUE(response->headers->IsKeepAlive());
3453 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423454 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043455 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323456
mmenked39192ee2015-12-09 00:57:233457 LoadTimingInfo load_timing_info;
3458 // CONNECT requests and responses are handled at the connect job level, so
3459 // the transaction does not yet have a connection.
3460 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3461
[email protected]49639fa2011-12-20 23:22:413462 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323463
mmenked39192ee2015-12-09 00:57:233464 rv =
3465 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3466 EXPECT_EQ(OK, callback2.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:323467
[email protected]2d2697f92009-02-18 21:00:323468 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233469 EXPECT_EQ(200, response->headers->response_code());
3470 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423471 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133472
mmenked39192ee2015-12-09 00:57:233473 // The password prompt info should not be set.
3474 EXPECT_FALSE(response->auth_challenge);
3475
3476 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3477 TestLoadTimingNotReusedWithPac(load_timing_info,
3478 CONNECT_TIMING_HAS_SSL_TIMES);
3479
3480 trans.reset();
[email protected]102e27c2011-02-23 01:01:313481 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323482}
3483
mmenkee71e15332015-10-07 16:39:543484// Test the case a proxy closes a socket while the challenge body is being
3485// drained.
3486TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
3487 HttpRequestInfo request;
3488 request.method = "GET";
3489 request.url = GURL("https://www.example.org/");
3490 // Ensure that proxy authentication is attempted even
3491 // when the no authentication data flag is set.
3492 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3493
3494 // Configure against proxy server "myproxy:70".
3495 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093496 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543497
danakj1fd259a02016-04-16 03:17:093498 std::unique_ptr<HttpTransaction> trans(
mmenkee71e15332015-10-07 16:39:543499 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3500
3501 // Since we have proxy, should try to establish tunnel.
3502 MockWrite data_writes1[] = {
3503 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173504 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543505 "Proxy-Connection: keep-alive\r\n\r\n"),
3506 };
3507
3508 // The proxy responds to the connect with a 407, using a persistent
3509 // connection.
3510 MockRead data_reads1[] = {
3511 // No credentials.
3512 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3513 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3514 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3515 // Server hands up in the middle of the body.
3516 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3517 };
3518
3519 MockWrite data_writes2[] = {
3520 // After calling trans->RestartWithAuth(), this is the request we should
3521 // be issuing -- the final header line contains the credentials.
3522 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173523 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543524 "Proxy-Connection: keep-alive\r\n"
3525 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3526
3527 MockWrite("GET / HTTP/1.1\r\n"
3528 "Host: www.example.org\r\n"
3529 "Connection: keep-alive\r\n\r\n"),
3530 };
3531
3532 MockRead data_reads2[] = {
3533 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3534
3535 MockRead("HTTP/1.1 200 OK\r\n"),
3536 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3537 MockRead("Content-Length: 5\r\n\r\n"),
3538 MockRead(SYNCHRONOUS, "hello"),
3539 };
3540
3541 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3542 data_writes1, arraysize(data_writes1));
3543 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3544 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3545 data_writes2, arraysize(data_writes2));
3546 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3547 SSLSocketDataProvider ssl(ASYNC, OK);
3548 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3549
3550 TestCompletionCallback callback;
3551
3552 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3553 EXPECT_EQ(OK, callback.GetResult(rv));
3554
3555 const HttpResponseInfo* response = trans->GetResponseInfo();
3556 ASSERT_TRUE(response);
3557 ASSERT_TRUE(response->headers);
3558 EXPECT_TRUE(response->headers->IsKeepAlive());
3559 EXPECT_EQ(407, response->headers->response_code());
3560 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3561
3562 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
3563 EXPECT_EQ(OK, callback.GetResult(rv));
3564
3565 response = trans->GetResponseInfo();
3566 ASSERT_TRUE(response);
3567 ASSERT_TRUE(response->headers);
3568 EXPECT_TRUE(response->headers->IsKeepAlive());
3569 EXPECT_EQ(200, response->headers->response_code());
3570 std::string body;
3571 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
3572 EXPECT_EQ("hello", body);
3573}
3574
[email protected]a8e9b162009-03-12 00:06:443575// Test that we don't read the response body when we fail to establish a tunnel,
3576// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:023577TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273578 HttpRequestInfo request;
3579 request.method = "GET";
bncce36dca22015-04-21 22:11:233580 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273581 request.load_flags = 0;
3582
[email protected]a8e9b162009-03-12 00:06:443583 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033584 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443585
danakj1fd259a02016-04-16 03:17:093586 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443587
danakj1fd259a02016-04-16 03:17:093588 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503589 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:443590
[email protected]a8e9b162009-03-12 00:06:443591 // Since we have proxy, should try to establish tunnel.
3592 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173593 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3594 "Host: www.example.org:443\r\n"
3595 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443596 };
3597
3598 // The proxy responds to the connect with a 407.
3599 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243600 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3601 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3602 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233603 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243604 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443605 };
3606
[email protected]31a2bfe2010-02-09 08:03:393607 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3608 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073609 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443610
[email protected]49639fa2011-12-20 23:22:413611 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443612
[email protected]49639fa2011-12-20 23:22:413613 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423614 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:443615
3616 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423617 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:443618
[email protected]1c773ea12009-04-28 19:58:423619 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243620 ASSERT_TRUE(response);
3621 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443622 EXPECT_TRUE(response->headers->IsKeepAlive());
3623 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423624 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443625
3626 std::string response_data;
3627 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423628 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:183629
3630 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313631 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443632}
3633
ttuttle7933c112015-01-06 00:55:243634// Test that we don't pass extraneous headers from the proxy's response to the
3635// caller when the proxy responds to CONNECT with 407.
3636TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3637 HttpRequestInfo request;
3638 request.method = "GET";
bncce36dca22015-04-21 22:11:233639 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243640 request.load_flags = 0;
3641
3642 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033643 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243644
danakj1fd259a02016-04-16 03:17:093645 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243646
danakj1fd259a02016-04-16 03:17:093647 std::unique_ptr<HttpTransaction> trans(
ttuttle7933c112015-01-06 00:55:243648 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3649
3650 // Since we have proxy, should try to establish tunnel.
3651 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173652 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3653 "Host: www.example.org:443\r\n"
3654 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243655 };
3656
3657 // The proxy responds to the connect with a 407.
3658 MockRead data_reads[] = {
3659 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3660 MockRead("X-Foo: bar\r\n"),
3661 MockRead("Set-Cookie: foo=bar\r\n"),
3662 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3663 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233664 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243665 };
3666
3667 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3668 arraysize(data_writes));
3669 session_deps_.socket_factory->AddSocketDataProvider(&data);
3670
3671 TestCompletionCallback callback;
3672
3673 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3674 EXPECT_EQ(ERR_IO_PENDING, rv);
3675
3676 rv = callback.WaitForResult();
3677 EXPECT_EQ(OK, rv);
3678
3679 const HttpResponseInfo* response = trans->GetResponseInfo();
3680 ASSERT_TRUE(response);
3681 ASSERT_TRUE(response->headers);
3682 EXPECT_TRUE(response->headers->IsKeepAlive());
3683 EXPECT_EQ(407, response->headers->response_code());
3684 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3685 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3686 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3687
3688 std::string response_data;
3689 rv = ReadTransaction(trans.get(), &response_data);
3690 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3691
3692 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3693 session->CloseAllConnections();
3694}
3695
[email protected]8fdbcd22010-05-05 02:54:523696// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3697// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023698TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523699 HttpRequestInfo request;
3700 request.method = "GET";
bncce36dca22015-04-21 22:11:233701 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523702 request.load_flags = 0;
3703
[email protected]cb9bf6ca2011-01-28 13:15:273704 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3706 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413707 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273708
[email protected]8fdbcd22010-05-05 02:54:523709 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233710 MockWrite(
3711 "GET / HTTP/1.1\r\n"
3712 "Host: www.example.org\r\n"
3713 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523714 };
3715
3716 MockRead data_reads1[] = {
3717 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3718 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3719 // Large content-length -- won't matter, as connection will be reset.
3720 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063721 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523722 };
3723
3724 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3725 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073726 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523727
[email protected]49639fa2011-12-20 23:22:413728 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523729
[email protected]49639fa2011-12-20 23:22:413730 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523731 EXPECT_EQ(ERR_IO_PENDING, rv);
3732
3733 rv = callback.WaitForResult();
3734 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3735}
3736
[email protected]7a67a8152010-11-05 18:31:103737// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3738// through a non-authenticating proxy. The request should fail with
3739// ERR_UNEXPECTED_PROXY_AUTH.
3740// Note that it is impossible to detect if an HTTP server returns a 407 through
3741// a non-authenticating proxy - there is nothing to indicate whether the
3742// response came from the proxy or the server, so it is treated as if the proxy
3743// issued the challenge.
[email protected]23e482282013-06-14 16:08:023744TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233745 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273746 HttpRequestInfo request;
3747 request.method = "GET";
bncce36dca22015-04-21 22:11:233748 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273749
rdsmith82957ad2015-09-16 19:42:033750 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513751 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073752 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093753 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103754
[email protected]7a67a8152010-11-05 18:31:103755 // Since we have proxy, should try to establish tunnel.
3756 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173757 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3758 "Host: www.example.org:443\r\n"
3759 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103760
rsleevidb16bb02015-11-12 23:47:173761 MockWrite("GET / HTTP/1.1\r\n"
3762 "Host: www.example.org\r\n"
3763 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103764 };
3765
3766 MockRead data_reads1[] = {
3767 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3768
3769 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3770 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3771 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063772 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103773 };
3774
3775 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3776 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073777 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063778 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103780
[email protected]49639fa2011-12-20 23:22:413781 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103782
danakj1fd259a02016-04-16 03:17:093783 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503784 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103785
[email protected]49639fa2011-12-20 23:22:413786 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103787 EXPECT_EQ(ERR_IO_PENDING, rv);
3788
3789 rv = callback1.WaitForResult();
3790 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463791 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403792 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103793 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403794 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103795 NetLog::PHASE_NONE);
3796 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403797 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103798 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3799 NetLog::PHASE_NONE);
3800}
[email protected]2df19bb2010-08-25 20:13:463801
mmenke2a1781d2015-10-07 19:25:333802// Test a proxy auth scheme that allows default credentials and a proxy server
3803// that uses non-persistent connections.
3804TEST_P(HttpNetworkTransactionTest,
3805 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3806 HttpRequestInfo request;
3807 request.method = "GET";
3808 request.url = GURL("https://www.example.org/");
3809
3810 // Configure against proxy server "myproxy:70".
3811 session_deps_.proxy_service =
3812 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3813
danakj1fd259a02016-04-16 03:17:093814 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333815 new HttpAuthHandlerMock::Factory());
3816 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093817 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333818 mock_handler->set_allows_default_credentials(true);
3819 auth_handler_factory->AddMockHandler(mock_handler.release(),
3820 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483821 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333822
3823 // Add NetLog just so can verify load timing information gets a NetLog ID.
3824 NetLog net_log;
3825 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093826 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333827
3828 // Since we have proxy, should try to establish tunnel.
3829 MockWrite data_writes1[] = {
3830 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173831 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333832 "Proxy-Connection: keep-alive\r\n\r\n"),
3833 };
3834
3835 // The proxy responds to the connect with a 407, using a non-persistent
3836 // connection.
3837 MockRead data_reads1[] = {
3838 // No credentials.
3839 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3840 MockRead("Proxy-Authenticate: Mock\r\n"),
3841 MockRead("Proxy-Connection: close\r\n\r\n"),
3842 };
3843
3844 // Since the first connection couldn't be reused, need to establish another
3845 // once given credentials.
3846 MockWrite data_writes2[] = {
3847 // After calling trans->RestartWithAuth(), this is the request we should
3848 // be issuing -- the final header line contains the credentials.
3849 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173850 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333851 "Proxy-Connection: keep-alive\r\n"
3852 "Proxy-Authorization: auth_token\r\n\r\n"),
3853
3854 MockWrite("GET / HTTP/1.1\r\n"
3855 "Host: www.example.org\r\n"
3856 "Connection: keep-alive\r\n\r\n"),
3857 };
3858
3859 MockRead data_reads2[] = {
3860 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3861
3862 MockRead("HTTP/1.1 200 OK\r\n"),
3863 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3864 MockRead("Content-Length: 5\r\n\r\n"),
3865 MockRead(SYNCHRONOUS, "hello"),
3866 };
3867
3868 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3869 data_writes1, arraysize(data_writes1));
3870 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3871 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3872 data_writes2, arraysize(data_writes2));
3873 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3874 SSLSocketDataProvider ssl(ASYNC, OK);
3875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3876
danakj1fd259a02016-04-16 03:17:093877 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333878 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3879
3880 TestCompletionCallback callback;
3881 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3882 EXPECT_EQ(OK, callback.GetResult(rv));
3883
3884 const HttpResponseInfo* response = trans->GetResponseInfo();
3885 ASSERT_TRUE(response);
3886 ASSERT_TRUE(response->headers);
3887 EXPECT_FALSE(response->headers->IsKeepAlive());
3888 EXPECT_EQ(407, response->headers->response_code());
3889 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3890 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523891 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333892
3893 LoadTimingInfo load_timing_info;
3894 // CONNECT requests and responses are handled at the connect job level, so
3895 // the transaction does not yet have a connection.
3896 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3897
3898 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3899 EXPECT_EQ(OK, callback.GetResult(rv));
3900 response = trans->GetResponseInfo();
3901 ASSERT_TRUE(response);
3902 ASSERT_TRUE(response->headers);
3903 EXPECT_TRUE(response->headers->IsKeepAlive());
3904 EXPECT_EQ(200, response->headers->response_code());
3905 EXPECT_EQ(5, response->headers->GetContentLength());
3906 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3907
3908 // The password prompt info should not be set.
3909 EXPECT_FALSE(response->auth_challenge);
3910
3911 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3912 TestLoadTimingNotReusedWithPac(load_timing_info,
3913 CONNECT_TIMING_HAS_SSL_TIMES);
3914
3915 trans.reset();
3916 session->CloseAllConnections();
3917}
3918
3919// Test a proxy auth scheme that allows default credentials and a proxy server
3920// that hangs up when credentials are initially sent.
3921TEST_P(HttpNetworkTransactionTest,
3922 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3923 HttpRequestInfo request;
3924 request.method = "GET";
3925 request.url = GURL("https://www.example.org/");
3926
3927 // Configure against proxy server "myproxy:70".
3928 session_deps_.proxy_service =
3929 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3930
danakj1fd259a02016-04-16 03:17:093931 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333932 new HttpAuthHandlerMock::Factory());
3933 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093934 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333935 mock_handler->set_allows_default_credentials(true);
3936 auth_handler_factory->AddMockHandler(mock_handler.release(),
3937 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483938 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333939
3940 // Add NetLog just so can verify load timing information gets a NetLog ID.
3941 NetLog net_log;
3942 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093943 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333944
3945 // Should try to establish tunnel.
3946 MockWrite data_writes1[] = {
3947 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173948 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333949 "Proxy-Connection: keep-alive\r\n\r\n"),
3950
3951 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173952 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333953 "Proxy-Connection: keep-alive\r\n"
3954 "Proxy-Authorization: auth_token\r\n\r\n"),
3955 };
3956
3957 // The proxy responds to the connect with a 407, using a non-persistent
3958 // connection.
3959 MockRead data_reads1[] = {
3960 // No credentials.
3961 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3962 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3963 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3964 };
3965
3966 // Since the first connection was closed, need to establish another once given
3967 // credentials.
3968 MockWrite data_writes2[] = {
3969 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173970 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333971 "Proxy-Connection: keep-alive\r\n"
3972 "Proxy-Authorization: auth_token\r\n\r\n"),
3973
3974 MockWrite("GET / HTTP/1.1\r\n"
3975 "Host: www.example.org\r\n"
3976 "Connection: keep-alive\r\n\r\n"),
3977 };
3978
3979 MockRead data_reads2[] = {
3980 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3981
3982 MockRead("HTTP/1.1 200 OK\r\n"),
3983 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3984 MockRead("Content-Length: 5\r\n\r\n"),
3985 MockRead(SYNCHRONOUS, "hello"),
3986 };
3987
3988 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3989 data_writes1, arraysize(data_writes1));
3990 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3991 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3992 data_writes2, arraysize(data_writes2));
3993 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3994 SSLSocketDataProvider ssl(ASYNC, OK);
3995 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3996
danakj1fd259a02016-04-16 03:17:093997 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333998 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3999
4000 TestCompletionCallback callback;
4001 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4002 EXPECT_EQ(OK, callback.GetResult(rv));
4003
4004 const HttpResponseInfo* response = trans->GetResponseInfo();
4005 ASSERT_TRUE(response);
4006 ASSERT_TRUE(response->headers);
4007 EXPECT_TRUE(response->headers->IsKeepAlive());
4008 EXPECT_EQ(407, response->headers->response_code());
4009 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4010 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4011 EXPECT_FALSE(response->auth_challenge);
4012
4013 LoadTimingInfo load_timing_info;
4014 // CONNECT requests and responses are handled at the connect job level, so
4015 // the transaction does not yet have a connection.
4016 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4017
4018 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4019 EXPECT_EQ(OK, callback.GetResult(rv));
4020
4021 response = trans->GetResponseInfo();
4022 ASSERT_TRUE(response);
4023 ASSERT_TRUE(response->headers);
4024 EXPECT_TRUE(response->headers->IsKeepAlive());
4025 EXPECT_EQ(200, response->headers->response_code());
4026 EXPECT_EQ(5, response->headers->GetContentLength());
4027 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4028
4029 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524030 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334031
4032 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4033 TestLoadTimingNotReusedWithPac(load_timing_info,
4034 CONNECT_TIMING_HAS_SSL_TIMES);
4035
4036 trans.reset();
4037 session->CloseAllConnections();
4038}
4039
4040// Test a proxy auth scheme that allows default credentials and a proxy server
4041// that hangs up when credentials are initially sent, and hangs up again when
4042// they are retried.
4043TEST_P(HttpNetworkTransactionTest,
4044 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4045 HttpRequestInfo request;
4046 request.method = "GET";
4047 request.url = GURL("https://www.example.org/");
4048
4049 // Configure against proxy server "myproxy:70".
4050 session_deps_.proxy_service =
4051 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4052
danakj1fd259a02016-04-16 03:17:094053 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334054 new HttpAuthHandlerMock::Factory());
4055 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094056 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334057 mock_handler->set_allows_default_credentials(true);
4058 auth_handler_factory->AddMockHandler(mock_handler.release(),
4059 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484060 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334061
4062 // Add NetLog just so can verify load timing information gets a NetLog ID.
4063 NetLog net_log;
4064 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094065 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334066
4067 // Should try to establish tunnel.
4068 MockWrite data_writes1[] = {
4069 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174070 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334071 "Proxy-Connection: keep-alive\r\n\r\n"),
4072
4073 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174074 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334075 "Proxy-Connection: keep-alive\r\n"
4076 "Proxy-Authorization: auth_token\r\n\r\n"),
4077 };
4078
4079 // The proxy responds to the connect with a 407, and then hangs up after the
4080 // second request is sent.
4081 MockRead data_reads1[] = {
4082 // No credentials.
4083 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4084 MockRead("Content-Length: 0\r\n"),
4085 MockRead("Proxy-Connection: keep-alive\r\n"),
4086 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4087 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4088 };
4089
4090 // HttpNetworkTransaction sees a reused connection that was closed with
4091 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4092 // request.
4093 MockWrite data_writes2[] = {
4094 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174095 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334096 "Proxy-Connection: keep-alive\r\n\r\n"),
4097 };
4098
4099 // The proxy, having had more than enough of us, just hangs up.
4100 MockRead data_reads2[] = {
4101 // No credentials.
4102 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4103 };
4104
4105 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4106 data_writes1, arraysize(data_writes1));
4107 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4108 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4109 data_writes2, arraysize(data_writes2));
4110 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4111
danakj1fd259a02016-04-16 03:17:094112 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4114
4115 TestCompletionCallback callback;
4116 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4117 EXPECT_EQ(OK, callback.GetResult(rv));
4118
4119 const HttpResponseInfo* response = trans->GetResponseInfo();
4120 ASSERT_TRUE(response);
4121 ASSERT_TRUE(response->headers);
4122 EXPECT_TRUE(response->headers->IsKeepAlive());
4123 EXPECT_EQ(407, response->headers->response_code());
4124 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4125 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4126 EXPECT_FALSE(response->auth_challenge);
4127
4128 LoadTimingInfo load_timing_info;
4129 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4130
4131 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4132 EXPECT_EQ(ERR_EMPTY_RESPONSE, callback.GetResult(rv));
4133
4134 trans.reset();
4135 session->CloseAllConnections();
4136}
4137
4138// Test a proxy auth scheme that allows default credentials and a proxy server
4139// that hangs up when credentials are initially sent, and sends a challenge
4140// again they are retried.
4141TEST_P(HttpNetworkTransactionTest,
4142 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4143 HttpRequestInfo request;
4144 request.method = "GET";
4145 request.url = GURL("https://www.example.org/");
4146
4147 // Configure against proxy server "myproxy:70".
4148 session_deps_.proxy_service =
4149 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4150
danakj1fd259a02016-04-16 03:17:094151 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334152 new HttpAuthHandlerMock::Factory());
4153 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094154 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334155 mock_handler->set_allows_default_credentials(true);
4156 auth_handler_factory->AddMockHandler(mock_handler.release(),
4157 HttpAuth::AUTH_PROXY);
4158 // Add another handler for the second challenge. It supports default
4159 // credentials, but they shouldn't be used, since they were already tried.
4160 mock_handler.reset(new HttpAuthHandlerMock());
4161 mock_handler->set_allows_default_credentials(true);
4162 auth_handler_factory->AddMockHandler(mock_handler.release(),
4163 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484164 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334165
4166 // Add NetLog just so can verify load timing information gets a NetLog ID.
4167 NetLog net_log;
4168 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094169 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334170
4171 // Should try to establish tunnel.
4172 MockWrite data_writes1[] = {
4173 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174174 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334175 "Proxy-Connection: keep-alive\r\n\r\n"),
4176 };
4177
4178 // The proxy responds to the connect with a 407, using a non-persistent
4179 // connection.
4180 MockRead data_reads1[] = {
4181 // No credentials.
4182 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4183 MockRead("Proxy-Authenticate: Mock\r\n"),
4184 MockRead("Proxy-Connection: close\r\n\r\n"),
4185 };
4186
4187 // Since the first connection was closed, need to establish another once given
4188 // credentials.
4189 MockWrite data_writes2[] = {
4190 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174191 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334192 "Proxy-Connection: keep-alive\r\n"
4193 "Proxy-Authorization: auth_token\r\n\r\n"),
4194 };
4195
4196 MockRead data_reads2[] = {
4197 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4198 MockRead("Proxy-Authenticate: Mock\r\n"),
4199 MockRead("Proxy-Connection: close\r\n\r\n"),
4200 };
4201
4202 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4203 data_writes1, arraysize(data_writes1));
4204 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4205 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4206 data_writes2, arraysize(data_writes2));
4207 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4208 SSLSocketDataProvider ssl(ASYNC, OK);
4209 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4210
danakj1fd259a02016-04-16 03:17:094211 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4213
4214 TestCompletionCallback callback;
4215 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4216 EXPECT_EQ(OK, callback.GetResult(rv));
4217
4218 const HttpResponseInfo* response = trans->GetResponseInfo();
4219 ASSERT_TRUE(response);
4220 ASSERT_TRUE(response->headers);
4221 EXPECT_EQ(407, response->headers->response_code());
4222 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4223 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4224 EXPECT_FALSE(response->auth_challenge);
4225
4226 LoadTimingInfo load_timing_info;
4227 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4228
4229 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4230 EXPECT_EQ(OK, callback.GetResult(rv));
4231 response = trans->GetResponseInfo();
4232 ASSERT_TRUE(response);
4233 ASSERT_TRUE(response->headers);
4234 EXPECT_EQ(407, response->headers->response_code());
4235 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4236 EXPECT_TRUE(response->auth_challenge);
4237
4238 trans.reset();
4239 session->CloseAllConnections();
4240}
4241
[email protected]029c83b62013-01-24 05:28:204242// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:024243TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204244 HttpRequestInfo request1;
4245 request1.method = "GET";
bncce36dca22015-04-21 22:11:234246 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204247
4248 HttpRequestInfo request2;
4249 request2.method = "GET";
bncce36dca22015-04-21 22:11:234250 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204251
4252 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034253 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514254 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074255 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094256 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204257
4258 // Since we have proxy, should try to establish tunnel.
4259 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174260 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4261 "Host: www.example.org:443\r\n"
4262 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204263
rsleevidb16bb02015-11-12 23:47:174264 MockWrite("GET /1 HTTP/1.1\r\n"
4265 "Host: www.example.org\r\n"
4266 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204267
rsleevidb16bb02015-11-12 23:47:174268 MockWrite("GET /2 HTTP/1.1\r\n"
4269 "Host: www.example.org\r\n"
4270 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204271 };
4272
4273 // The proxy responds to the connect with a 407, using a persistent
4274 // connection.
4275 MockRead data_reads1[] = {
4276 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4277
4278 MockRead("HTTP/1.1 200 OK\r\n"),
4279 MockRead("Content-Length: 1\r\n\r\n"),
4280 MockRead(SYNCHRONOUS, "1"),
4281
4282 MockRead("HTTP/1.1 200 OK\r\n"),
4283 MockRead("Content-Length: 2\r\n\r\n"),
4284 MockRead(SYNCHRONOUS, "22"),
4285 };
4286
4287 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4288 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074289 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204290 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074291 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204292
4293 TestCompletionCallback callback1;
danakj1fd259a02016-04-16 03:17:094294 std::unique_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:504295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204296
4297 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
4298 EXPECT_EQ(ERR_IO_PENDING, rv);
4299
4300 rv = callback1.WaitForResult();
4301 EXPECT_EQ(OK, rv);
4302
4303 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524304 ASSERT_TRUE(response1);
4305 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204306 EXPECT_EQ(1, response1->headers->GetContentLength());
4307
4308 LoadTimingInfo load_timing_info1;
4309 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4310 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4311
4312 trans1.reset();
4313
4314 TestCompletionCallback callback2;
danakj1fd259a02016-04-16 03:17:094315 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504316 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204317
4318 rv = trans2->Start(&request2, callback2.callback(), log.bound());
4319 EXPECT_EQ(ERR_IO_PENDING, rv);
4320
4321 rv = callback2.WaitForResult();
4322 EXPECT_EQ(OK, rv);
4323
4324 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524325 ASSERT_TRUE(response2);
4326 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204327 EXPECT_EQ(2, response2->headers->GetContentLength());
4328
4329 LoadTimingInfo load_timing_info2;
4330 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4331 TestLoadTimingReused(load_timing_info2);
4332
4333 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4334
4335 trans2.reset();
4336 session->CloseAllConnections();
4337}
4338
4339// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:024340TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204341 HttpRequestInfo request1;
4342 request1.method = "GET";
bncce36dca22015-04-21 22:11:234343 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204344
4345 HttpRequestInfo request2;
4346 request2.method = "GET";
bncce36dca22015-04-21 22:11:234347 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204348
4349 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034350 session_deps_.proxy_service =
4351 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514352 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074353 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204355
4356 // Since we have proxy, should try to establish tunnel.
4357 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174358 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4359 "Host: www.example.org:443\r\n"
4360 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204361
rsleevidb16bb02015-11-12 23:47:174362 MockWrite("GET /1 HTTP/1.1\r\n"
4363 "Host: www.example.org\r\n"
4364 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204365
rsleevidb16bb02015-11-12 23:47:174366 MockWrite("GET /2 HTTP/1.1\r\n"
4367 "Host: www.example.org\r\n"
4368 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204369 };
4370
4371 // The proxy responds to the connect with a 407, using a persistent
4372 // connection.
4373 MockRead data_reads1[] = {
4374 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4375
4376 MockRead("HTTP/1.1 200 OK\r\n"),
4377 MockRead("Content-Length: 1\r\n\r\n"),
4378 MockRead(SYNCHRONOUS, "1"),
4379
4380 MockRead("HTTP/1.1 200 OK\r\n"),
4381 MockRead("Content-Length: 2\r\n\r\n"),
4382 MockRead(SYNCHRONOUS, "22"),
4383 };
4384
4385 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4386 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074387 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204388 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074389 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204390
4391 TestCompletionCallback callback1;
danakj1fd259a02016-04-16 03:17:094392 std::unique_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:504393 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204394
4395 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
4396 EXPECT_EQ(ERR_IO_PENDING, rv);
4397
4398 rv = callback1.WaitForResult();
4399 EXPECT_EQ(OK, rv);
4400
4401 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524402 ASSERT_TRUE(response1);
4403 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204404 EXPECT_EQ(1, response1->headers->GetContentLength());
4405
4406 LoadTimingInfo load_timing_info1;
4407 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4408 TestLoadTimingNotReusedWithPac(load_timing_info1,
4409 CONNECT_TIMING_HAS_SSL_TIMES);
4410
4411 trans1.reset();
4412
4413 TestCompletionCallback callback2;
danakj1fd259a02016-04-16 03:17:094414 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504415 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204416
4417 rv = trans2->Start(&request2, callback2.callback(), log.bound());
4418 EXPECT_EQ(ERR_IO_PENDING, rv);
4419
4420 rv = callback2.WaitForResult();
4421 EXPECT_EQ(OK, rv);
4422
4423 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524424 ASSERT_TRUE(response2);
4425 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204426 EXPECT_EQ(2, response2->headers->GetContentLength());
4427
4428 LoadTimingInfo load_timing_info2;
4429 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4430 TestLoadTimingReusedWithPac(load_timing_info2);
4431
4432 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4433
4434 trans2.reset();
4435 session->CloseAllConnections();
4436}
4437
[email protected]2df19bb2010-08-25 20:13:464438// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024439TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274440 HttpRequestInfo request;
4441 request.method = "GET";
bncce36dca22015-04-21 22:11:234442 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274443
[email protected]2df19bb2010-08-25 20:13:464444 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034445 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514446 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074447 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464449
[email protected]2df19bb2010-08-25 20:13:464450 // Since we have proxy, should use full url
4451 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234452 MockWrite(
4453 "GET http://www.example.org/ HTTP/1.1\r\n"
4454 "Host: www.example.org\r\n"
4455 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464456 };
4457
4458 MockRead data_reads1[] = {
4459 MockRead("HTTP/1.1 200 OK\r\n"),
4460 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4461 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064462 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464463 };
4464
4465 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4466 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074467 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064468 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074469 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464470
[email protected]49639fa2011-12-20 23:22:414471 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464472
danakj1fd259a02016-04-16 03:17:094473 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504474 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504475
[email protected]49639fa2011-12-20 23:22:414476 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464477 EXPECT_EQ(ERR_IO_PENDING, rv);
4478
4479 rv = callback1.WaitForResult();
4480 EXPECT_EQ(OK, rv);
4481
[email protected]58e32bb2013-01-21 18:23:254482 LoadTimingInfo load_timing_info;
4483 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4484 TestLoadTimingNotReused(load_timing_info,
4485 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4486
[email protected]2df19bb2010-08-25 20:13:464487 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524488 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464489
4490 EXPECT_TRUE(response->headers->IsKeepAlive());
4491 EXPECT_EQ(200, response->headers->response_code());
4492 EXPECT_EQ(100, response->headers->GetContentLength());
4493 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4494
4495 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524496 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464497}
4498
[email protected]7642b5ae2010-09-01 20:55:174499// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024500TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274501 HttpRequestInfo request;
4502 request.method = "GET";
bncce36dca22015-04-21 22:11:234503 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274504 request.load_flags = 0;
4505
[email protected]7642b5ae2010-09-01 20:55:174506 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034507 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514508 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074509 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094510 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174511
bncce36dca22015-04-21 22:11:234512 // fetch http://www.example.org/ via SPDY
danakj1fd259a02016-04-16 03:17:094513 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:494514 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134515 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174516
danakj1fd259a02016-04-16 03:17:094517 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554518 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:094519 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554520 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174521 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134522 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174523 };
4524
rch8e6c6c42015-05-01 14:05:134525 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4526 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074527 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174528
[email protected]8ddf8322012-02-23 18:08:064529 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384530 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074531 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174532
[email protected]49639fa2011-12-20 23:22:414533 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174534
danakj1fd259a02016-04-16 03:17:094535 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504536 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504537
[email protected]49639fa2011-12-20 23:22:414538 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:174539 EXPECT_EQ(ERR_IO_PENDING, rv);
4540
4541 rv = callback1.WaitForResult();
4542 EXPECT_EQ(OK, rv);
4543
[email protected]58e32bb2013-01-21 18:23:254544 LoadTimingInfo load_timing_info;
4545 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4546 TestLoadTimingNotReused(load_timing_info,
4547 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4548
[email protected]7642b5ae2010-09-01 20:55:174549 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524550 ASSERT_TRUE(response);
4551 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024552 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174553
4554 std::string response_data;
4555 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234556 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174557}
4558
[email protected]1c173852014-06-19 12:51:504559// Verifies that a session which races and wins against the owning transaction
4560// (completing prior to host resolution), doesn't fail the transaction.
4561// Regression test for crbug.com/334413.
4562TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
4563 HttpRequestInfo request;
4564 request.method = "GET";
bncce36dca22015-04-21 22:11:234565 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504566 request.load_flags = 0;
4567
4568 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034569 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514570 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504571 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094572 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504573
bncce36dca22015-04-21 22:11:234574 // Fetch http://www.example.org/ through the SPDY proxy.
danakj1fd259a02016-04-16 03:17:094575 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:494576 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134577 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:504578
danakj1fd259a02016-04-16 03:17:094579 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554580 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094581 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554582 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]1c173852014-06-19 12:51:504583 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134584 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504585 };
4586
rch8e6c6c42015-05-01 14:05:134587 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4588 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504589 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4590
4591 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384592 ssl.SetNextProto(GetProtocol());
[email protected]1c173852014-06-19 12:51:504593 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4594
4595 TestCompletionCallback callback1;
4596
danakj1fd259a02016-04-16 03:17:094597 std::unique_ptr<HttpTransaction> trans(
[email protected]1c173852014-06-19 12:51:504598 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4599
4600 // Stall the hostname resolution begun by the transaction.
4601 session_deps_.host_resolver->set_synchronous_mode(false);
4602 session_deps_.host_resolver->set_ondemand_mode(true);
4603
4604 int rv = trans->Start(&request, callback1.callback(), log.bound());
4605 EXPECT_EQ(ERR_IO_PENDING, rv);
4606
4607 // Race a session to the proxy, which completes first.
4608 session_deps_.host_resolver->set_ondemand_mode(false);
4609 SpdySessionKey key(
4610 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4611 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424612 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504613
4614 // Unstall the resolution begun by the transaction.
4615 session_deps_.host_resolver->set_ondemand_mode(true);
4616 session_deps_.host_resolver->ResolveAllPending();
4617
4618 EXPECT_FALSE(callback1.have_result());
4619 rv = callback1.WaitForResult();
4620 EXPECT_EQ(OK, rv);
4621
4622 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524623 ASSERT_TRUE(response);
4624 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024625 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504626
4627 std::string response_data;
4628 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4629 EXPECT_EQ(kUploadData, response_data);
4630}
4631
[email protected]dc7bd1c52010-11-12 00:01:134632// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024633TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274634 HttpRequestInfo request;
4635 request.method = "GET";
bncce36dca22015-04-21 22:11:234636 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274637 request.load_flags = 0;
4638
[email protected]79cb5c12011-09-12 13:12:044639 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034640 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514641 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074642 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094643 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134644
[email protected]dc7bd1c52010-11-12 00:01:134645 // The first request will be a bare GET, the second request will be a
4646 // GET with a Proxy-Authorization header.
danakj1fd259a02016-04-16 03:17:094647 std::unique_ptr<SpdySerializedFrame> req_get(
bnc38dcd392016-02-09 23:19:494648 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384649 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134650 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464651 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134652 };
danakj1fd259a02016-04-16 03:17:094653 std::unique_ptr<SpdySerializedFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:464654 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
bncb03b1092016-04-06 11:19:554655 arraysize(kExtraAuthorizationHeaders) / 2, 3,
4656 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134657 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134658 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134659 };
4660
4661 // The first response is a 407 proxy authentication challenge, and the second
4662 // response will be a 200 response since the second request includes a valid
4663 // Authorization header.
4664 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464665 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134666 };
danakj1fd259a02016-04-16 03:17:094667 std::unique_ptr<SpdySerializedFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:024668 spdy_util_.ConstructSpdySynReplyError(
bncb03b1092016-04-06 11:19:554669 "407 Proxy Authentication Required", kExtraAuthenticationHeaders,
4670 arraysize(kExtraAuthenticationHeaders) / 2, 1));
danakj1fd259a02016-04-16 03:17:094671 std::unique_ptr<SpdySerializedFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:024672 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:094673 std::unique_ptr<SpdySerializedFrame> resp_data(
[email protected]23e482282013-06-14 16:08:024674 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:094675 std::unique_ptr<SpdySerializedFrame> body_data(
bncb03b1092016-04-06 11:19:554676 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134677 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134678 CreateMockRead(*resp_authentication, 1),
4679 CreateMockRead(*body_authentication, 2),
4680 CreateMockRead(*resp_data, 4),
4681 CreateMockRead(*body_data, 5),
4682 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134683 };
4684
rch8e6c6c42015-05-01 14:05:134685 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4686 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074687 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134688
[email protected]8ddf8322012-02-23 18:08:064689 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384690 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074691 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134692
[email protected]49639fa2011-12-20 23:22:414693 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134694
danakj1fd259a02016-04-16 03:17:094695 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504696 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:134697
[email protected]49639fa2011-12-20 23:22:414698 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:134699 EXPECT_EQ(ERR_IO_PENDING, rv);
4700
4701 rv = callback1.WaitForResult();
4702 EXPECT_EQ(OK, rv);
4703
4704 const HttpResponseInfo* const response = trans->GetResponseInfo();
4705
wezca1070932016-05-26 20:30:524706 ASSERT_TRUE(response);
4707 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134708 EXPECT_EQ(407, response->headers->response_code());
4709 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434710 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134711
[email protected]49639fa2011-12-20 23:22:414712 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134713
[email protected]49639fa2011-12-20 23:22:414714 rv = trans->RestartWithAuth(
4715 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:134716 EXPECT_EQ(ERR_IO_PENDING, rv);
4717
4718 rv = callback2.WaitForResult();
4719 EXPECT_EQ(OK, rv);
4720
4721 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
4722
wezca1070932016-05-26 20:30:524723 ASSERT_TRUE(response_restart);
4724 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134725 EXPECT_EQ(200, response_restart->headers->response_code());
4726 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524727 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134728}
4729
[email protected]d9da5fe2010-10-13 22:37:164730// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:024731TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274732 HttpRequestInfo request;
4733 request.method = "GET";
bncce36dca22015-04-21 22:11:234734 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274735 request.load_flags = 0;
4736
[email protected]d9da5fe2010-10-13 22:37:164737 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034738 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514739 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074740 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094741 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164742
danakj1fd259a02016-04-16 03:17:094743 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504744 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164745
bncce36dca22015-04-21 22:11:234746 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094747 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234748 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4749 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164750
bncce36dca22015-04-21 22:11:234751 const char get[] =
4752 "GET / HTTP/1.1\r\n"
4753 "Host: www.example.org\r\n"
4754 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094755 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024756 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
danakj1fd259a02016-04-16 03:17:094757 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:024758 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164759 const char resp[] = "HTTP/1.1 200 OK\r\n"
4760 "Content-Length: 10\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094761 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024762 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
danakj1fd259a02016-04-16 03:17:094763 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024764 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
danakj1fd259a02016-04-16 03:17:094765 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204766 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:044767
4768 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134769 CreateMockWrite(*connect, 0),
4770 CreateMockWrite(*wrapped_get, 2),
4771 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044772 };
4773
[email protected]d9da5fe2010-10-13 22:37:164774 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134775 CreateMockRead(*conn_resp, 1, ASYNC),
4776 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
4777 CreateMockRead(*wrapped_body, 4, ASYNC),
4778 CreateMockRead(*wrapped_body, 5, ASYNC),
4779 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164780 };
4781
rch8e6c6c42015-05-01 14:05:134782 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4783 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074784 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164785
[email protected]8ddf8322012-02-23 18:08:064786 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384787 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074788 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064789 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074790 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164791
[email protected]49639fa2011-12-20 23:22:414792 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164793
[email protected]49639fa2011-12-20 23:22:414794 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164795 EXPECT_EQ(ERR_IO_PENDING, rv);
4796
4797 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:134798 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:164799
[email protected]58e32bb2013-01-21 18:23:254800 LoadTimingInfo load_timing_info;
4801 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4802 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4803
[email protected]d9da5fe2010-10-13 22:37:164804 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524805 ASSERT_TRUE(response);
4806 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164807 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4808
4809 std::string response_data;
4810 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4811 EXPECT_EQ("1234567890", response_data);
4812}
4813
4814// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:024815TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
rdsmithebb50aa2015-11-12 03:44:384816 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
4817
[email protected]cb9bf6ca2011-01-28 13:15:274818 HttpRequestInfo request;
4819 request.method = "GET";
bncce36dca22015-04-21 22:11:234820 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274821 request.load_flags = 0;
4822
[email protected]d9da5fe2010-10-13 22:37:164823 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034824 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514825 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074826 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164828
danakj1fd259a02016-04-16 03:17:094829 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504830 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164831
bncce36dca22015-04-21 22:11:234832 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094833 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234834 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4835 // fetch https://www.example.org/ via SPDY
4836 const char kMyUrl[] = "https://www.example.org/";
danakj1fd259a02016-04-16 03:17:094837 std::unique_ptr<SpdySerializedFrame> get(
bnc38dcd392016-02-09 23:19:494838 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
danakj1fd259a02016-04-16 03:17:094839 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024840 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
danakj1fd259a02016-04-16 03:17:094841 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:024842 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094843 std::unique_ptr<SpdySerializedFrame> get_resp(
rdsmithebb50aa2015-11-12 03:44:384844 spdy_util_wrapped.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094845 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024846 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
danakj1fd259a02016-04-16 03:17:094847 std::unique_ptr<SpdySerializedFrame> body(
bncb03b1092016-04-06 11:19:554848 spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:094849 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024850 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
danakj1fd259a02016-04-16 03:17:094851 std::unique_ptr<SpdySerializedFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:204852 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
danakj1fd259a02016-04-16 03:17:094853 std::unique_ptr<SpdySerializedFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:204854 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:044855
4856 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:094857 CreateMockWrite(*connect, 0),
4858 CreateMockWrite(*wrapped_get, 2),
4859 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:044860 CreateMockWrite(*window_update_body, 7),
4861 };
4862
[email protected]d9da5fe2010-10-13 22:37:164863 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:094864 CreateMockRead(*conn_resp, 1, ASYNC),
4865 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:134866 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:094867 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134868 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164869 };
4870
rch32320842015-05-16 15:57:094871 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4872 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074873 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164874
[email protected]8ddf8322012-02-23 18:08:064875 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384876 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074877 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064878 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384879 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074880 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164881
[email protected]49639fa2011-12-20 23:22:414882 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164883
[email protected]49639fa2011-12-20 23:22:414884 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164885 EXPECT_EQ(ERR_IO_PENDING, rv);
4886
rch32320842015-05-16 15:57:094887 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:554888 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:094889 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:594890 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:164891 rv = callback1.WaitForResult();
4892 EXPECT_EQ(OK, rv);
4893
[email protected]58e32bb2013-01-21 18:23:254894 LoadTimingInfo load_timing_info;
4895 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4896 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4897
[email protected]d9da5fe2010-10-13 22:37:164898 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524899 ASSERT_TRUE(response);
4900 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024901 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:164902
4903 std::string response_data;
4904 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234905 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:164906}
4907
4908// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024909TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:274910 HttpRequestInfo request;
4911 request.method = "GET";
bncce36dca22015-04-21 22:11:234912 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274913 request.load_flags = 0;
4914
[email protected]d9da5fe2010-10-13 22:37:164915 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034916 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514917 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074918 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164920
danakj1fd259a02016-04-16 03:17:094921 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164923
bncce36dca22015-04-21 22:11:234924 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094925 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234926 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:094927 std::unique_ptr<SpdySerializedFrame> get(
[email protected]c10b20852013-05-15 21:29:204928 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:164929
4930 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134931 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:164932 };
4933
danakj1fd259a02016-04-16 03:17:094934 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554935 spdy_util_.ConstructSpdySynReplyError(1));
danakj1fd259a02016-04-16 03:17:094936 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554937 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:164938 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134939 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:164940 };
4941
rch8e6c6c42015-05-01 14:05:134942 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4943 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074944 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164945
[email protected]8ddf8322012-02-23 18:08:064946 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384947 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074948 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064949 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384950 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074951 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164952
[email protected]49639fa2011-12-20 23:22:414953 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164954
[email protected]49639fa2011-12-20 23:22:414955 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164956 EXPECT_EQ(ERR_IO_PENDING, rv);
4957
4958 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:174959 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:164960
ttuttle960fcbf2016-04-19 13:26:324961 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:164962}
4963
[email protected]f6c63db52013-02-02 00:35:224964// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4965// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024966TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224967 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
4968 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034969 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514970 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074971 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094972 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504973 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224974
4975 HttpRequestInfo request1;
4976 request1.method = "GET";
bncce36dca22015-04-21 22:11:234977 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224978 request1.load_flags = 0;
4979
4980 HttpRequestInfo request2;
4981 request2.method = "GET";
bncce36dca22015-04-21 22:11:234982 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224983 request2.load_flags = 0;
4984
bncce36dca22015-04-21 22:11:234985 // CONNECT to www.example.org:443 via SPDY.
danakj1fd259a02016-04-16 03:17:094986 std::unique_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234987 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:094988 std::unique_ptr<SpdySerializedFrame> conn_resp1(
[email protected]23e482282013-06-14 16:08:024989 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224990
bncce36dca22015-04-21 22:11:234991 // Fetch https://www.example.org/ via HTTP.
4992 const char get1[] =
4993 "GET / HTTP/1.1\r\n"
4994 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224995 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094996 std::unique_ptr<SpdySerializedFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024997 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224998 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4999 "Content-Length: 1\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095000 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:025001 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
danakj1fd259a02016-04-16 03:17:095002 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
[email protected]23e482282013-06-14 16:08:025003 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
danakj1fd259a02016-04-16 03:17:095004 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:205005 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:225006
bncce36dca22015-04-21 22:11:235007 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295008 SpdyHeaderBlock connect2_block;
bnc7ecc1122015-09-28 13:22:495009 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]745aa9c2014-06-27 02:21:295010 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
rdsmithebb50aa2015-11-12 03:44:385011 if (GetProtocol() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:325012 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
5013 } else {
bnc6b996d532015-07-29 10:51:325014 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
bnc7ecc1122015-09-28 13:22:495015 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
bnc6b996d532015-07-29 10:51:325016 }
danakj1fd259a02016-04-16 03:17:095017 std::unique_ptr<SpdySerializedFrame> connect2(
bnc38dcd392016-02-09 23:19:495018 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395019
danakj1fd259a02016-04-16 03:17:095020 std::unique_ptr<SpdySerializedFrame> conn_resp2(
[email protected]23e482282013-06-14 16:08:025021 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225022
bncce36dca22015-04-21 22:11:235023 // Fetch https://mail.example.org/ via HTTP.
5024 const char get2[] =
5025 "GET / HTTP/1.1\r\n"
5026 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225027 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095028 std::unique_ptr<SpdySerializedFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:025029 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225030 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5031 "Content-Length: 2\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095032 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:025033 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
danakj1fd259a02016-04-16 03:17:095034 std::unique_ptr<SpdySerializedFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:025035 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225036
5037 MockWrite spdy_writes[] = {
5038 CreateMockWrite(*connect1, 0),
5039 CreateMockWrite(*wrapped_get1, 2),
5040 CreateMockWrite(*connect2, 5),
5041 CreateMockWrite(*wrapped_get2, 7),
5042 };
5043
5044 MockRead spdy_reads[] = {
5045 CreateMockRead(*conn_resp1, 1, ASYNC),
5046 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
5047 CreateMockRead(*wrapped_body1, 4, ASYNC),
5048 CreateMockRead(*conn_resp2, 6, ASYNC),
5049 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
5050 CreateMockRead(*wrapped_body2, 9, ASYNC),
5051 MockRead(ASYNC, 0, 10),
5052 };
5053
mmenke11eb5152015-06-09 14:50:505054 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5055 arraysize(spdy_writes));
5056 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225057
5058 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:385059 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:505060 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225061 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505062 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225063 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505064 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225065
5066 TestCompletionCallback callback;
5067
danakj1fd259a02016-04-16 03:17:095068 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505069 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225070 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505071 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225072
5073 LoadTimingInfo load_timing_info;
5074 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5075 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5076
5077 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525078 ASSERT_TRUE(response);
5079 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225080 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5081
5082 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295083 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505084 rv = trans->Read(buf.get(), 256, callback.callback());
5085 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225086
danakj1fd259a02016-04-16 03:17:095087 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:505088 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225089 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505090 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225091
5092 LoadTimingInfo load_timing_info2;
5093 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5094 // Even though the SPDY connection is reused, a new tunnelled connection has
5095 // to be created, so the socket's load timing looks like a fresh connection.
5096 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5097
5098 // The requests should have different IDs, since they each are using their own
5099 // separate stream.
5100 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5101
mmenke11eb5152015-06-09 14:50:505102 rv = trans2->Read(buf.get(), 256, callback.callback());
5103 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225104}
5105
5106// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5107// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:025108TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225109 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5110 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035111 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515112 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075113 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095114 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505115 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225116
5117 HttpRequestInfo request1;
5118 request1.method = "GET";
bncce36dca22015-04-21 22:11:235119 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225120 request1.load_flags = 0;
5121
5122 HttpRequestInfo request2;
5123 request2.method = "GET";
bncce36dca22015-04-21 22:11:235124 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225125 request2.load_flags = 0;
5126
bncce36dca22015-04-21 22:11:235127 // CONNECT to www.example.org:443 via SPDY.
danakj1fd259a02016-04-16 03:17:095128 std::unique_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235129 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:095130 std::unique_ptr<SpdySerializedFrame> conn_resp1(
[email protected]23e482282013-06-14 16:08:025131 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225132
bncce36dca22015-04-21 22:11:235133 // Fetch https://www.example.org/ via HTTP.
5134 const char get1[] =
5135 "GET / HTTP/1.1\r\n"
5136 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225137 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095138 std::unique_ptr<SpdySerializedFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:025139 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225140 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5141 "Content-Length: 1\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095142 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:025143 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
danakj1fd259a02016-04-16 03:17:095144 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
[email protected]23e482282013-06-14 16:08:025145 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
danakj1fd259a02016-04-16 03:17:095146 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:205147 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:225148
bncce36dca22015-04-21 22:11:235149 // Fetch https://www.example.org/2 via HTTP.
5150 const char get2[] =
5151 "GET /2 HTTP/1.1\r\n"
5152 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225153 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095154 std::unique_ptr<SpdySerializedFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:025155 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225156 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5157 "Content-Length: 2\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095158 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:025159 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
danakj1fd259a02016-04-16 03:17:095160 std::unique_ptr<SpdySerializedFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:025161 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225162
5163 MockWrite spdy_writes[] = {
5164 CreateMockWrite(*connect1, 0),
5165 CreateMockWrite(*wrapped_get1, 2),
5166 CreateMockWrite(*wrapped_get2, 5),
5167 };
5168
5169 MockRead spdy_reads[] = {
5170 CreateMockRead(*conn_resp1, 1, ASYNC),
5171 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
5172 CreateMockRead(*wrapped_body1, 4, ASYNC),
5173 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
5174 CreateMockRead(*wrapped_body2, 7, ASYNC),
5175 MockRead(ASYNC, 0, 8),
5176 };
5177
mmenke11eb5152015-06-09 14:50:505178 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5179 arraysize(spdy_writes));
5180 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225181
5182 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:385183 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:505184 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225185 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505186 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225187
5188 TestCompletionCallback callback;
5189
danakj1fd259a02016-04-16 03:17:095190 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225192 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
5193 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:225194
5195 rv = callback.WaitForResult();
5196 EXPECT_EQ(OK, rv);
5197
5198 LoadTimingInfo load_timing_info;
5199 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5200 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5201
5202 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525203 ASSERT_TRUE(response);
5204 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225205 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5206
5207 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295208 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505209 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225210 trans.reset();
5211
danakj1fd259a02016-04-16 03:17:095212 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:505213 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225214 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
5215 EXPECT_EQ(ERR_IO_PENDING, rv);
5216
[email protected]f6c63db52013-02-02 00:35:225217 rv = callback.WaitForResult();
5218 EXPECT_EQ(OK, rv);
5219
5220 LoadTimingInfo load_timing_info2;
5221 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5222 TestLoadTimingReused(load_timing_info2);
5223
5224 // The requests should have the same ID.
5225 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5226
[email protected]90499482013-06-01 00:39:505227 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225228}
5229
5230// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5231// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:505232TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225233 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035234 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515235 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075236 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095237 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505238 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225239
5240 HttpRequestInfo request1;
5241 request1.method = "GET";
bncce36dca22015-04-21 22:11:235242 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225243 request1.load_flags = 0;
5244
5245 HttpRequestInfo request2;
5246 request2.method = "GET";
bncce36dca22015-04-21 22:11:235247 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225248 request2.load_flags = 0;
5249
bncce36dca22015-04-21 22:11:235250 // http://www.example.org/
danakj1fd259a02016-04-16 03:17:095251 std::unique_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:235252 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
danakj1fd259a02016-04-16 03:17:095253 std::unique_ptr<SpdySerializedFrame> get1(
bnc38dcd392016-02-09 23:19:495254 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
danakj1fd259a02016-04-16 03:17:095255 std::unique_ptr<SpdySerializedFrame> get_resp1(
[email protected]23e482282013-06-14 16:08:025256 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:095257 std::unique_ptr<SpdySerializedFrame> body1(
[email protected]23e482282013-06-14 16:08:025258 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385259 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225260
bncce36dca22015-04-21 22:11:235261 // http://mail.example.org/
danakj1fd259a02016-04-16 03:17:095262 std::unique_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:235263 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
danakj1fd259a02016-04-16 03:17:095264 std::unique_ptr<SpdySerializedFrame> get2(
bnc38dcd392016-02-09 23:19:495265 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, true));
danakj1fd259a02016-04-16 03:17:095266 std::unique_ptr<SpdySerializedFrame> get_resp2(
[email protected]23e482282013-06-14 16:08:025267 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:095268 std::unique_ptr<SpdySerializedFrame> body2(
[email protected]23e482282013-06-14 16:08:025269 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225270
5271 MockWrite spdy_writes[] = {
5272 CreateMockWrite(*get1, 0),
5273 CreateMockWrite(*get2, 3),
5274 };
5275
5276 MockRead spdy_reads[] = {
5277 CreateMockRead(*get_resp1, 1, ASYNC),
5278 CreateMockRead(*body1, 2, ASYNC),
5279 CreateMockRead(*get_resp2, 4, ASYNC),
5280 CreateMockRead(*body2, 5, ASYNC),
5281 MockRead(ASYNC, 0, 6),
5282 };
5283
mmenke11eb5152015-06-09 14:50:505284 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5285 arraysize(spdy_writes));
5286 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225287
5288 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:385289 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:505290 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225291
5292 TestCompletionCallback callback;
5293
danakj1fd259a02016-04-16 03:17:095294 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225296 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505297 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225298
5299 LoadTimingInfo load_timing_info;
5300 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5301 TestLoadTimingNotReused(load_timing_info,
5302 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5303
5304 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525305 ASSERT_TRUE(response);
5306 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025307 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225308
5309 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295310 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505311 rv = trans->Read(buf.get(), 256, callback.callback());
5312 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225313 // Delete the first request, so the second one can reuse the socket.
5314 trans.reset();
5315
danakj1fd259a02016-04-16 03:17:095316 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:505317 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225318 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505319 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225320
5321 LoadTimingInfo load_timing_info2;
5322 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5323 TestLoadTimingReused(load_timing_info2);
5324
5325 // The requests should have the same ID.
5326 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5327
mmenke11eb5152015-06-09 14:50:505328 rv = trans2->Read(buf.get(), 256, callback.callback());
5329 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225330}
5331
[email protected]2df19bb2010-08-25 20:13:465332// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:025333TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465334 HttpRequestInfo request;
5335 request.method = "GET";
bncce36dca22015-04-21 22:11:235336 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465337 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295338 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465339
[email protected]79cb5c12011-09-12 13:12:045340 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035341 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515342 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075343 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095344 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275345
[email protected]2df19bb2010-08-25 20:13:465346 // Since we have proxy, should use full url
5347 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235348 MockWrite(
5349 "GET http://www.example.org/ HTTP/1.1\r\n"
5350 "Host: www.example.org\r\n"
5351 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465352
bncce36dca22015-04-21 22:11:235353 // After calling trans->RestartWithAuth(), this is the request we should
5354 // be issuing -- the final header line contains the credentials.
5355 MockWrite(
5356 "GET http://www.example.org/ HTTP/1.1\r\n"
5357 "Host: www.example.org\r\n"
5358 "Proxy-Connection: keep-alive\r\n"
5359 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465360 };
5361
5362 // The proxy responds to the GET with a 407, using a persistent
5363 // connection.
5364 MockRead data_reads1[] = {
5365 // No credentials.
5366 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5367 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5368 MockRead("Proxy-Connection: keep-alive\r\n"),
5369 MockRead("Content-Length: 0\r\n\r\n"),
5370
5371 MockRead("HTTP/1.1 200 OK\r\n"),
5372 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5373 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065374 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465375 };
5376
5377 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5378 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075379 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065380 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075381 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465382
[email protected]49639fa2011-12-20 23:22:415383 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465384
danakj1fd259a02016-04-16 03:17:095385 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505386 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505387
[email protected]49639fa2011-12-20 23:22:415388 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:465389 EXPECT_EQ(ERR_IO_PENDING, rv);
5390
5391 rv = callback1.WaitForResult();
5392 EXPECT_EQ(OK, rv);
5393
[email protected]58e32bb2013-01-21 18:23:255394 LoadTimingInfo load_timing_info;
5395 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5396 TestLoadTimingNotReused(load_timing_info,
5397 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5398
[email protected]2df19bb2010-08-25 20:13:465399 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525400 ASSERT_TRUE(response);
5401 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465402 EXPECT_EQ(407, response->headers->response_code());
5403 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435404 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465405
[email protected]49639fa2011-12-20 23:22:415406 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465407
[email protected]49639fa2011-12-20 23:22:415408 rv = trans->RestartWithAuth(
5409 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:465410 EXPECT_EQ(ERR_IO_PENDING, rv);
5411
5412 rv = callback2.WaitForResult();
5413 EXPECT_EQ(OK, rv);
5414
[email protected]58e32bb2013-01-21 18:23:255415 load_timing_info = LoadTimingInfo();
5416 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5417 // Retrying with HTTP AUTH is considered to be reusing a socket.
5418 TestLoadTimingReused(load_timing_info);
5419
[email protected]2df19bb2010-08-25 20:13:465420 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525421 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465422
5423 EXPECT_TRUE(response->headers->IsKeepAlive());
5424 EXPECT_EQ(200, response->headers->response_code());
5425 EXPECT_EQ(100, response->headers->GetContentLength());
5426 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5427
5428 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525429 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465430}
5431
[email protected]23e482282013-06-14 16:08:025432void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085433 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425434 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085435 request.method = "GET";
bncce36dca22015-04-21 22:11:235436 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085437 request.load_flags = 0;
5438
[email protected]cb9bf6ca2011-01-28 13:15:275439 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035440 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095441 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275442
[email protected]c744cf22009-02-27 07:28:085443 // Since we have proxy, should try to establish tunnel.
5444 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175445 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5446 "Host: www.example.org:443\r\n"
5447 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085448 };
5449
5450 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235451 status, MockRead("Content-Length: 10\r\n\r\n"),
5452 // No response body because the test stops reading here.
5453 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085454 };
5455
[email protected]31a2bfe2010-02-09 08:03:395456 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5457 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075458 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085459
[email protected]49639fa2011-12-20 23:22:415460 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085461
danakj1fd259a02016-04-16 03:17:095462 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505463 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505464
[email protected]49639fa2011-12-20 23:22:415465 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425466 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:085467
5468 rv = callback.WaitForResult();
5469 EXPECT_EQ(expected_status, rv);
5470}
5471
[email protected]23e482282013-06-14 16:08:025472void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235473 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085474 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425475 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085476}
5477
[email protected]23e482282013-06-14 16:08:025478TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085479 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5480}
5481
[email protected]23e482282013-06-14 16:08:025482TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085483 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5484}
5485
[email protected]23e482282013-06-14 16:08:025486TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085487 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5488}
5489
[email protected]23e482282013-06-14 16:08:025490TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085491 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5492}
5493
[email protected]23e482282013-06-14 16:08:025494TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085495 ConnectStatusHelper(
5496 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5497}
5498
[email protected]23e482282013-06-14 16:08:025499TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085500 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5501}
5502
[email protected]23e482282013-06-14 16:08:025503TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085504 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5505}
5506
[email protected]23e482282013-06-14 16:08:025507TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085508 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5509}
5510
[email protected]23e482282013-06-14 16:08:025511TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085512 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5513}
5514
[email protected]23e482282013-06-14 16:08:025515TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085516 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5517}
5518
[email protected]23e482282013-06-14 16:08:025519TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085520 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5521}
5522
[email protected]23e482282013-06-14 16:08:025523TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085524 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5525}
5526
[email protected]23e482282013-06-14 16:08:025527TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085528 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5529}
5530
[email protected]23e482282013-06-14 16:08:025531TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085532 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5533}
5534
[email protected]23e482282013-06-14 16:08:025535TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085536 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5537}
5538
[email protected]23e482282013-06-14 16:08:025539TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085540 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5541}
5542
[email protected]0a17aab32014-04-24 03:32:375543TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
5544 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5545}
5546
[email protected]23e482282013-06-14 16:08:025547TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085548 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5549}
5550
[email protected]23e482282013-06-14 16:08:025551TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085552 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5553}
5554
[email protected]23e482282013-06-14 16:08:025555TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085556 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5557}
5558
[email protected]23e482282013-06-14 16:08:025559TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085560 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5561}
5562
[email protected]23e482282013-06-14 16:08:025563TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085564 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5565}
5566
[email protected]23e482282013-06-14 16:08:025567TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085568 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5569}
5570
[email protected]23e482282013-06-14 16:08:025571TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085572 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5573}
5574
[email protected]23e482282013-06-14 16:08:025575TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085576 ConnectStatusHelperWithExpectedStatus(
5577 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545578 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085579}
5580
[email protected]23e482282013-06-14 16:08:025581TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085582 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5583}
5584
[email protected]23e482282013-06-14 16:08:025585TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085586 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5587}
5588
[email protected]23e482282013-06-14 16:08:025589TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085590 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5591}
5592
[email protected]23e482282013-06-14 16:08:025593TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085594 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5595}
5596
[email protected]23e482282013-06-14 16:08:025597TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085598 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5599}
5600
[email protected]23e482282013-06-14 16:08:025601TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085602 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5603}
5604
[email protected]23e482282013-06-14 16:08:025605TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085606 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5607}
5608
[email protected]23e482282013-06-14 16:08:025609TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085610 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5611}
5612
[email protected]23e482282013-06-14 16:08:025613TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085614 ConnectStatusHelper(
5615 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5616}
5617
[email protected]23e482282013-06-14 16:08:025618TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085619 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5620}
5621
[email protected]23e482282013-06-14 16:08:025622TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085623 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5624}
5625
[email protected]23e482282013-06-14 16:08:025626TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085627 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5628}
5629
[email protected]23e482282013-06-14 16:08:025630TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085631 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5632}
5633
[email protected]23e482282013-06-14 16:08:025634TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085635 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5636}
5637
[email protected]23e482282013-06-14 16:08:025638TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085639 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5640}
5641
[email protected]23e482282013-06-14 16:08:025642TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085643 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5644}
5645
[email protected]038e9a32008-10-08 22:40:165646// Test the flow when both the proxy server AND origin server require
5647// authentication. Again, this uses basic auth for both since that is
5648// the simplest to mock.
[email protected]23e482282013-06-14 16:08:025649TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275650 HttpRequestInfo request;
5651 request.method = "GET";
bncce36dca22015-04-21 22:11:235652 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275653 request.load_flags = 0;
5654
[email protected]038e9a32008-10-08 22:40:165655 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035656 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095657 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075658
danakj1fd259a02016-04-16 03:17:095659 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415660 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:165661
[email protected]f9ee6b52008-11-08 06:46:235662 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235663 MockWrite(
5664 "GET http://www.example.org/ HTTP/1.1\r\n"
5665 "Host: www.example.org\r\n"
5666 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235667 };
5668
[email protected]038e9a32008-10-08 22:40:165669 MockRead data_reads1[] = {
5670 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5671 // Give a couple authenticate options (only the middle one is actually
5672 // supported).
[email protected]22927ad2009-09-21 19:56:195673 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165674 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5675 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5676 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5677 // Large content-length -- won't matter, as connection will be reset.
5678 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065679 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165680 };
5681
5682 // After calling trans->RestartWithAuth() the first time, this is the
5683 // request we should be issuing -- the final header line contains the
5684 // proxy's credentials.
5685 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235686 MockWrite(
5687 "GET http://www.example.org/ HTTP/1.1\r\n"
5688 "Host: www.example.org\r\n"
5689 "Proxy-Connection: keep-alive\r\n"
5690 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165691 };
5692
5693 // Now the proxy server lets the request pass through to origin server.
5694 // The origin server responds with a 401.
5695 MockRead data_reads2[] = {
5696 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5697 // Note: We are using the same realm-name as the proxy server. This is
5698 // completely valid, as realms are unique across hosts.
5699 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5700 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5701 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065702 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165703 };
5704
5705 // After calling trans->RestartWithAuth() the second time, we should send
5706 // the credentials for both the proxy and origin server.
5707 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235708 MockWrite(
5709 "GET http://www.example.org/ HTTP/1.1\r\n"
5710 "Host: www.example.org\r\n"
5711 "Proxy-Connection: keep-alive\r\n"
5712 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5713 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165714 };
5715
5716 // Lastly we get the desired content.
5717 MockRead data_reads3[] = {
5718 MockRead("HTTP/1.0 200 OK\r\n"),
5719 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5720 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065721 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165722 };
5723
[email protected]31a2bfe2010-02-09 08:03:395724 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5725 data_writes1, arraysize(data_writes1));
5726 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5727 data_writes2, arraysize(data_writes2));
5728 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5729 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075730 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5731 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5732 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165733
[email protected]49639fa2011-12-20 23:22:415734 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165735
[email protected]49639fa2011-12-20 23:22:415736 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425737 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165738
5739 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425740 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165741
[email protected]1c773ea12009-04-28 19:58:425742 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525743 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045744 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165745
[email protected]49639fa2011-12-20 23:22:415746 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165747
[email protected]49639fa2011-12-20 23:22:415748 rv = trans->RestartWithAuth(
5749 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425750 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165751
5752 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425753 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165754
5755 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525756 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045757 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165758
[email protected]49639fa2011-12-20 23:22:415759 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165760
[email protected]49639fa2011-12-20 23:22:415761 rv = trans->RestartWithAuth(
5762 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425763 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165764
5765 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425766 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165767
5768 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525769 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165770 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165771}
[email protected]4ddaf2502008-10-23 18:26:195772
[email protected]ea9dc9a2009-09-05 00:43:325773// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5774// can't hook into its internals to cause it to generate predictable NTLM
5775// authorization headers.
5776#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295777// The NTLM authentication unit tests were generated by capturing the HTTP
5778// requests and responses using Fiddler 2 and inspecting the generated random
5779// bytes in the debugger.
5780
5781// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:025782TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425783 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245784 request.method = "GET";
5785 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545786
5787 // Ensure load is not disrupted by flags which suppress behaviour specific
5788 // to other auth schemes.
5789 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245790
[email protected]cb9bf6ca2011-01-28 13:15:275791 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5792 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275794
[email protected]3f918782009-02-28 01:29:245795 MockWrite data_writes1[] = {
5796 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5797 "Host: 172.22.68.17\r\n"
5798 "Connection: keep-alive\r\n\r\n"),
5799 };
5800
5801 MockRead data_reads1[] = {
5802 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045803 // Negotiate and NTLM are often requested together. However, we only want
5804 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5805 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245806 MockRead("WWW-Authenticate: NTLM\r\n"),
5807 MockRead("Connection: close\r\n"),
5808 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365809 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245810 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065811 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245812 };
5813
5814 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225815 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:245816 // request we should be issuing -- the final header line contains a Type
5817 // 1 message.
5818 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5819 "Host: 172.22.68.17\r\n"
5820 "Connection: keep-alive\r\n"
5821 "Authorization: NTLM "
5822 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5823
5824 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5825 // (the credentials for the origin server). The second request continues
5826 // on the same connection.
5827 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5828 "Host: 172.22.68.17\r\n"
5829 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:295830 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5831 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5832 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5833 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5834 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245835 };
5836
5837 MockRead data_reads2[] = {
5838 // The origin server responds with a Type 2 message.
5839 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5840 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295841 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245842 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5843 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5844 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5845 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5846 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5847 "BtAAAAAAA=\r\n"),
5848 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365849 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245850 MockRead("You are not authorized to view this page\r\n"),
5851
5852 // Lastly we get the desired content.
5853 MockRead("HTTP/1.1 200 OK\r\n"),
5854 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5855 MockRead("Content-Length: 13\r\n\r\n"),
5856 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065857 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245858 };
5859
[email protected]31a2bfe2010-02-09 08:03:395860 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5861 data_writes1, arraysize(data_writes1));
5862 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5863 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075864 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5865 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245866
[email protected]49639fa2011-12-20 23:22:415867 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245868
danakj1fd259a02016-04-16 03:17:095869 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505870 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505871
[email protected]49639fa2011-12-20 23:22:415872 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425873 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245874
5875 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425876 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245877
[email protected]0757e7702009-03-27 04:00:225878 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5879
[email protected]1c773ea12009-04-28 19:58:425880 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525881 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045882 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245883
[email protected]49639fa2011-12-20 23:22:415884 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255885
[email protected]f3cf9802011-10-28 18:44:585886 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415887 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:255888 EXPECT_EQ(ERR_IO_PENDING, rv);
5889
5890 rv = callback2.WaitForResult();
5891 EXPECT_EQ(OK, rv);
5892
5893 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5894
5895 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525896 ASSERT_TRUE(response);
5897 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255898
[email protected]49639fa2011-12-20 23:22:415899 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245900
[email protected]49639fa2011-12-20 23:22:415901 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425902 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245903
[email protected]0757e7702009-03-27 04:00:225904 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425905 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245906
5907 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525908 ASSERT_TRUE(response);
5909 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245910 EXPECT_EQ(13, response->headers->GetContentLength());
5911}
5912
[email protected]385a4672009-03-11 22:21:295913// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:025914TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425915 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295916 request.method = "GET";
5917 request.url = GURL("http://172.22.68.17/kids/login.aspx");
5918 request.load_flags = 0;
5919
[email protected]cb9bf6ca2011-01-28 13:15:275920 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5921 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095922 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275923
[email protected]385a4672009-03-11 22:21:295924 MockWrite data_writes1[] = {
5925 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5926 "Host: 172.22.68.17\r\n"
5927 "Connection: keep-alive\r\n\r\n"),
5928 };
5929
5930 MockRead data_reads1[] = {
5931 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045932 // Negotiate and NTLM are often requested together. However, we only want
5933 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5934 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:295935 MockRead("WWW-Authenticate: NTLM\r\n"),
5936 MockRead("Connection: close\r\n"),
5937 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365938 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295939 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065940 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295941 };
5942
5943 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225944 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295945 // request we should be issuing -- the final header line contains a Type
5946 // 1 message.
5947 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5948 "Host: 172.22.68.17\r\n"
5949 "Connection: keep-alive\r\n"
5950 "Authorization: NTLM "
5951 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5952
5953 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5954 // (the credentials for the origin server). The second request continues
5955 // on the same connection.
5956 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5957 "Host: 172.22.68.17\r\n"
5958 "Connection: keep-alive\r\n"
5959 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5960 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5961 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
5962 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
5963 "4Ww7b7E=\r\n\r\n"),
5964 };
5965
5966 MockRead data_reads2[] = {
5967 // The origin server responds with a Type 2 message.
5968 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5969 MockRead("WWW-Authenticate: NTLM "
5970 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
5971 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5972 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5973 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5974 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5975 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5976 "BtAAAAAAA=\r\n"),
5977 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365978 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295979 MockRead("You are not authorized to view this page\r\n"),
5980
5981 // Wrong password.
5982 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:295983 MockRead("WWW-Authenticate: NTLM\r\n"),
5984 MockRead("Connection: close\r\n"),
5985 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365986 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295987 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065988 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295989 };
5990
5991 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:225992 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295993 // request we should be issuing -- the final header line contains a Type
5994 // 1 message.
5995 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5996 "Host: 172.22.68.17\r\n"
5997 "Connection: keep-alive\r\n"
5998 "Authorization: NTLM "
5999 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
6000
6001 // After calling trans->RestartWithAuth(), we should send a Type 3 message
6002 // (the credentials for the origin server). The second request continues
6003 // on the same connection.
6004 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6005 "Host: 172.22.68.17\r\n"
6006 "Connection: keep-alive\r\n"
6007 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6008 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6009 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6010 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6011 "+4MUm7c=\r\n\r\n"),
6012 };
6013
6014 MockRead data_reads3[] = {
6015 // The origin server responds with a Type 2 message.
6016 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6017 MockRead("WWW-Authenticate: NTLM "
6018 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6019 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6020 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6021 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6022 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6023 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6024 "BtAAAAAAA=\r\n"),
6025 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366026 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296027 MockRead("You are not authorized to view this page\r\n"),
6028
6029 // Lastly we get the desired content.
6030 MockRead("HTTP/1.1 200 OK\r\n"),
6031 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6032 MockRead("Content-Length: 13\r\n\r\n"),
6033 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066034 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296035 };
6036
[email protected]31a2bfe2010-02-09 08:03:396037 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6038 data_writes1, arraysize(data_writes1));
6039 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6040 data_writes2, arraysize(data_writes2));
6041 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6042 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076043 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6044 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6045 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296046
[email protected]49639fa2011-12-20 23:22:416047 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296048
danakj1fd259a02016-04-16 03:17:096049 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506050 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:506051
[email protected]49639fa2011-12-20 23:22:416052 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426053 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:296054
6055 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426056 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:296057
[email protected]0757e7702009-03-27 04:00:226058 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296059
[email protected]1c773ea12009-04-28 19:58:426060 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526061 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046062 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296063
[email protected]49639fa2011-12-20 23:22:416064 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296065
[email protected]0757e7702009-03-27 04:00:226066 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:586067 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:416068 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426069 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:296070
[email protected]10af5fe72011-01-31 16:17:256071 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426072 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:296073
[email protected]0757e7702009-03-27 04:00:226074 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416075 TestCompletionCallback callback3;
6076 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426077 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:256078 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426079 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226080 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6081
6082 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526083 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046084 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226085
[email protected]49639fa2011-12-20 23:22:416086 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226087
6088 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:586089 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:416090 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:256091 EXPECT_EQ(ERR_IO_PENDING, rv);
6092
6093 rv = callback4.WaitForResult();
6094 EXPECT_EQ(OK, rv);
6095
6096 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6097
[email protected]49639fa2011-12-20 23:22:416098 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256099
6100 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:416101 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:426102 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226103
6104 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426105 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226106
[email protected]385a4672009-03-11 22:21:296107 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526108 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296109 EXPECT_EQ(13, response->headers->GetContentLength());
6110}
[email protected]ea9dc9a2009-09-05 00:43:326111#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296112
[email protected]4ddaf2502008-10-23 18:26:196113// Test reading a server response which has only headers, and no body.
6114// After some maximum number of bytes is consumed, the transaction should
6115// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:026116TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426117 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196118 request.method = "GET";
bncce36dca22015-04-21 22:11:236119 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196120 request.load_flags = 0;
6121
danakj1fd259a02016-04-16 03:17:096122 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6123 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416124 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276125
[email protected]b75b7b2f2009-10-06 00:54:536126 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436127 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536128 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196129
6130 MockRead data_reads[] = {
6131 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066132 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196133 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066134 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196135 };
[email protected]31a2bfe2010-02-09 08:03:396136 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076137 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196138
[email protected]49639fa2011-12-20 23:22:416139 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196140
[email protected]49639fa2011-12-20 23:22:416141 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426142 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:196143
6144 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426145 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:196146}
[email protected]f4e426b2008-11-05 00:24:496147
6148// Make sure that we don't try to reuse a TCPClientSocket when failing to
6149// establish tunnel.
6150// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:026151TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:236152 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276153 HttpRequestInfo request;
6154 request.method = "GET";
bncce36dca22015-04-21 22:11:236155 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276156 request.load_flags = 0;
6157
[email protected]f4e426b2008-11-05 00:24:496158 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036159 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016160
danakj1fd259a02016-04-16 03:17:096161 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496162
danakj1fd259a02016-04-16 03:17:096163 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506164 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:496165
[email protected]f4e426b2008-11-05 00:24:496166 // Since we have proxy, should try to establish tunnel.
6167 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176168 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6169 "Host: www.example.org:443\r\n"
6170 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496171 };
6172
[email protected]77848d12008-11-14 00:00:226173 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496174 // connection. Usually a proxy would return 501 (not implemented),
6175 // or 200 (tunnel established).
6176 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236177 MockRead("HTTP/1.1 404 Not Found\r\n"),
6178 MockRead("Content-Length: 10\r\n\r\n"),
6179 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496180 };
6181
[email protected]31a2bfe2010-02-09 08:03:396182 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6183 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076184 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496185
[email protected]49639fa2011-12-20 23:22:416186 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496187
[email protected]49639fa2011-12-20 23:22:416188 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426189 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:496190
6191 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426192 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:496193
[email protected]b4404c02009-04-10 16:38:526194 // Empty the current queue. This is necessary because idle sockets are
6195 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556196 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526197
[email protected]f4e426b2008-11-05 00:24:496198 // We now check to make sure the TCPClientSocket was not added back to
6199 // the pool.
[email protected]90499482013-06-01 00:39:506200 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496201 trans.reset();
fdoray92e35a72016-06-10 15:54:556202 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496203 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506204 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496205}
[email protected]372d34a2008-11-05 21:30:516206
[email protected]1b157c02009-04-21 01:55:406207// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:026208TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426209 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406210 request.method = "GET";
bncce36dca22015-04-21 22:11:236211 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406212 request.load_flags = 0;
6213
danakj1fd259a02016-04-16 03:17:096214 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276215
danakj1fd259a02016-04-16 03:17:096216 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506217 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276218
[email protected]1b157c02009-04-21 01:55:406219 MockRead data_reads[] = {
6220 // A part of the response body is received with the response headers.
6221 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6222 // The rest of the response body is received in two parts.
6223 MockRead("lo"),
6224 MockRead(" world"),
6225 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066226 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406227 };
6228
[email protected]31a2bfe2010-02-09 08:03:396229 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076230 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406231
[email protected]49639fa2011-12-20 23:22:416232 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406233
[email protected]49639fa2011-12-20 23:22:416234 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426235 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:406236
6237 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426238 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:406239
[email protected]1c773ea12009-04-28 19:58:426240 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526241 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406242
wezca1070932016-05-26 20:30:526243 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406244 std::string status_line = response->headers->GetStatusLine();
6245 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6246
[email protected]90499482013-06-01 00:39:506247 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406248
6249 std::string response_data;
6250 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426251 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:406252 EXPECT_EQ("hello world", response_data);
6253
6254 // Empty the current queue. This is necessary because idle sockets are
6255 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556256 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406257
6258 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506259 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406260}
6261
[email protected]76a505b2010-08-25 06:23:006262// Make sure that we recycle a SSL socket after reading all of the response
6263// body.
[email protected]23e482282013-06-14 16:08:026264TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006265 HttpRequestInfo request;
6266 request.method = "GET";
bncce36dca22015-04-21 22:11:236267 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006268 request.load_flags = 0;
6269
6270 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236271 MockWrite(
6272 "GET / HTTP/1.1\r\n"
6273 "Host: www.example.org\r\n"
6274 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006275 };
6276
6277 MockRead data_reads[] = {
6278 MockRead("HTTP/1.1 200 OK\r\n"),
6279 MockRead("Content-Length: 11\r\n\r\n"),
6280 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066281 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006282 };
6283
[email protected]8ddf8322012-02-23 18:08:066284 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006286
6287 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6288 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076289 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006290
[email protected]49639fa2011-12-20 23:22:416291 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006292
danakj1fd259a02016-04-16 03:17:096293 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6294 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006296
[email protected]49639fa2011-12-20 23:22:416297 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006298
6299 EXPECT_EQ(ERR_IO_PENDING, rv);
6300 EXPECT_EQ(OK, callback.WaitForResult());
6301
6302 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526303 ASSERT_TRUE(response);
6304 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006305 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6306
[email protected]90499482013-06-01 00:39:506307 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006308
6309 std::string response_data;
6310 rv = ReadTransaction(trans.get(), &response_data);
6311 EXPECT_EQ(OK, rv);
6312 EXPECT_EQ("hello world", response_data);
6313
6314 // Empty the current queue. This is necessary because idle sockets are
6315 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556316 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006317
6318 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506319 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006320}
6321
6322// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6323// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:026324TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006325 HttpRequestInfo request;
6326 request.method = "GET";
bncce36dca22015-04-21 22:11:236327 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006328 request.load_flags = 0;
6329
6330 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236331 MockWrite(
6332 "GET / HTTP/1.1\r\n"
6333 "Host: www.example.org\r\n"
6334 "Connection: keep-alive\r\n\r\n"),
6335 MockWrite(
6336 "GET / HTTP/1.1\r\n"
6337 "Host: www.example.org\r\n"
6338 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006339 };
6340
6341 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426342 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6343 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006344
[email protected]8ddf8322012-02-23 18:08:066345 SSLSocketDataProvider ssl(ASYNC, OK);
6346 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076347 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6348 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006349
6350 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6351 data_writes, arraysize(data_writes));
6352 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6353 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076354 session_deps_.socket_factory->AddSocketDataProvider(&data);
6355 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006356
[email protected]49639fa2011-12-20 23:22:416357 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006358
danakj1fd259a02016-04-16 03:17:096359 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6360 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506361 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006362
[email protected]49639fa2011-12-20 23:22:416363 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006364
6365 EXPECT_EQ(ERR_IO_PENDING, rv);
6366 EXPECT_EQ(OK, callback.WaitForResult());
6367
6368 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526369 ASSERT_TRUE(response);
6370 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006371 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6372
[email protected]90499482013-06-01 00:39:506373 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006374
6375 std::string response_data;
6376 rv = ReadTransaction(trans.get(), &response_data);
6377 EXPECT_EQ(OK, rv);
6378 EXPECT_EQ("hello world", response_data);
6379
6380 // Empty the current queue. This is necessary because idle sockets are
6381 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556382 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006383
6384 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506385 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006386
6387 // Now start the second transaction, which should reuse the previous socket.
6388
[email protected]90499482013-06-01 00:39:506389 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006390
[email protected]49639fa2011-12-20 23:22:416391 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006392
6393 EXPECT_EQ(ERR_IO_PENDING, rv);
6394 EXPECT_EQ(OK, callback.WaitForResult());
6395
6396 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526397 ASSERT_TRUE(response);
6398 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006399 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6400
[email protected]90499482013-06-01 00:39:506401 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006402
6403 rv = ReadTransaction(trans.get(), &response_data);
6404 EXPECT_EQ(OK, rv);
6405 EXPECT_EQ("hello world", response_data);
6406
6407 // Empty the current queue. This is necessary because idle sockets are
6408 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556409 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006410
6411 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506412 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006413}
6414
[email protected]b4404c02009-04-10 16:38:526415// Make sure that we recycle a socket after a zero-length response.
6416// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:026417TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426418 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526419 request.method = "GET";
bncce36dca22015-04-21 22:11:236420 request.url = GURL(
6421 "http://www.example.org/csi?v=3&s=web&action=&"
6422 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6423 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6424 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526425 request.load_flags = 0;
6426
danakj1fd259a02016-04-16 03:17:096427 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276428
[email protected]b4404c02009-04-10 16:38:526429 MockRead data_reads[] = {
6430 MockRead("HTTP/1.1 204 No Content\r\n"
6431 "Content-Length: 0\r\n"
6432 "Content-Type: text/html\r\n\r\n"),
6433 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066434 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526435 };
6436
[email protected]31a2bfe2010-02-09 08:03:396437 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076438 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526439
mmenkecc2298e2015-12-07 18:20:186440 // Transaction must be created after the MockReads, so it's destroyed before
6441 // them.
danakj1fd259a02016-04-16 03:17:096442 std::unique_ptr<HttpTransaction> trans(
mmenkecc2298e2015-12-07 18:20:186443 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6444
[email protected]49639fa2011-12-20 23:22:416445 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526446
[email protected]49639fa2011-12-20 23:22:416447 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426448 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:526449
6450 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426451 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:526452
[email protected]1c773ea12009-04-28 19:58:426453 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526454 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526455
wezca1070932016-05-26 20:30:526456 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526457 std::string status_line = response->headers->GetStatusLine();
6458 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6459
[email protected]90499482013-06-01 00:39:506460 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526461
6462 std::string response_data;
6463 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426464 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:526465 EXPECT_EQ("", response_data);
6466
6467 // Empty the current queue. This is necessary because idle sockets are
6468 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556469 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526470
6471 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506472 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526473}
6474
[email protected]23e482282013-06-14 16:08:026475TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096476 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226477 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:096478 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:226479 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276480
[email protected]1c773ea12009-04-28 19:58:426481 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516482 // Transaction 1: a GET request that succeeds. The socket is recycled
6483 // after use.
6484 request[0].method = "GET";
6485 request[0].url = GURL("http://www.google.com/");
6486 request[0].load_flags = 0;
6487 // Transaction 2: a POST request. Reuses the socket kept alive from
6488 // transaction 1. The first attempts fails when writing the POST data.
6489 // This causes the transaction to retry with a new socket. The second
6490 // attempt succeeds.
6491 request[1].method = "POST";
6492 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276493 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516494 request[1].load_flags = 0;
6495
danakj1fd259a02016-04-16 03:17:096496 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516497
6498 // The first socket is used for transaction 1 and the first attempt of
6499 // transaction 2.
6500
6501 // The response of transaction 1.
6502 MockRead data_reads1[] = {
6503 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6504 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066505 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516506 };
6507 // The mock write results of transaction 1 and the first attempt of
6508 // transaction 2.
6509 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066510 MockWrite(SYNCHRONOUS, 64), // GET
6511 MockWrite(SYNCHRONOUS, 93), // POST
6512 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516513 };
[email protected]31a2bfe2010-02-09 08:03:396514 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6515 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516516
6517 // The second socket is used for the second attempt of transaction 2.
6518
6519 // The response of transaction 2.
6520 MockRead data_reads2[] = {
6521 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6522 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066523 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516524 };
6525 // The mock write results of the second attempt of transaction 2.
6526 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066527 MockWrite(SYNCHRONOUS, 93), // POST
6528 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516529 };
[email protected]31a2bfe2010-02-09 08:03:396530 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6531 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516532
[email protected]bb88e1d32013-05-03 23:11:076533 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6534 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516535
thestig9d3bb0c2015-01-24 00:49:516536 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516537 "hello world", "welcome"
6538 };
6539
6540 for (int i = 0; i < 2; ++i) {
danakj1fd259a02016-04-16 03:17:096541 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506542 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:516543
[email protected]49639fa2011-12-20 23:22:416544 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516545
[email protected]49639fa2011-12-20 23:22:416546 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426547 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:516548
6549 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426550 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516551
[email protected]1c773ea12009-04-28 19:58:426552 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526553 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516554
wezca1070932016-05-26 20:30:526555 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516556 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6557
6558 std::string response_data;
6559 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426560 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516561 EXPECT_EQ(kExpectedResponseData[i], response_data);
6562 }
6563}
[email protected]f9ee6b52008-11-08 06:46:236564
6565// Test the request-challenge-retry sequence for basic auth when there is
6566// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166567// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:026568TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426569 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236570 request.method = "GET";
bncce36dca22015-04-21 22:11:236571 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416572 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296573
danakj1fd259a02016-04-16 03:17:096574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6575 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416576 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276577
[email protected]a97cca42009-08-14 01:00:296578 // The password contains an escaped character -- for this test to pass it
6579 // will need to be unescaped by HttpNetworkTransaction.
6580 EXPECT_EQ("b%40r", request.url.password());
6581
[email protected]f9ee6b52008-11-08 06:46:236582 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236583 MockWrite(
6584 "GET / HTTP/1.1\r\n"
6585 "Host: www.example.org\r\n"
6586 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236587 };
6588
6589 MockRead data_reads1[] = {
6590 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6591 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6592 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066593 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236594 };
6595
[email protected]2262e3a2012-05-22 16:08:166596 // After the challenge above, the transaction will be restarted using the
6597 // identity from the url (foo, b@r) to answer the challenge.
6598 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236599 MockWrite(
6600 "GET / HTTP/1.1\r\n"
6601 "Host: www.example.org\r\n"
6602 "Connection: keep-alive\r\n"
6603 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166604 };
6605
6606 MockRead data_reads2[] = {
6607 MockRead("HTTP/1.0 200 OK\r\n"),
6608 MockRead("Content-Length: 100\r\n\r\n"),
6609 MockRead(SYNCHRONOUS, OK),
6610 };
6611
[email protected]31a2bfe2010-02-09 08:03:396612 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6613 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166614 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6615 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076616 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6617 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236618
[email protected]49639fa2011-12-20 23:22:416619 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:416620 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426621 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236622 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426623 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:166624 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6625
6626 TestCompletionCallback callback2;
6627 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6628 EXPECT_EQ(ERR_IO_PENDING, rv);
6629 rv = callback2.WaitForResult();
6630 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226631 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6632
[email protected]2262e3a2012-05-22 16:08:166633 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526634 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166635
6636 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526637 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166638
6639 EXPECT_EQ(100, response->headers->GetContentLength());
6640
6641 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556642 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166643}
6644
6645// Test the request-challenge-retry sequence for basic auth when there is an
6646// incorrect identity in the URL. The identity from the URL should be used only
6647// once.
[email protected]23e482282013-06-14 16:08:026648TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166649 HttpRequestInfo request;
6650 request.method = "GET";
6651 // Note: the URL has a username:password in it. The password "baz" is
6652 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236653 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166654
6655 request.load_flags = LOAD_NORMAL;
6656
danakj1fd259a02016-04-16 03:17:096657 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6658 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416659 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:166660
6661 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236662 MockWrite(
6663 "GET / HTTP/1.1\r\n"
6664 "Host: www.example.org\r\n"
6665 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166666 };
6667
6668 MockRead data_reads1[] = {
6669 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6670 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6671 MockRead("Content-Length: 10\r\n\r\n"),
6672 MockRead(SYNCHRONOUS, ERR_FAILED),
6673 };
6674
6675 // After the challenge above, the transaction will be restarted using the
6676 // identity from the url (foo, baz) to answer the challenge.
6677 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236678 MockWrite(
6679 "GET / HTTP/1.1\r\n"
6680 "Host: www.example.org\r\n"
6681 "Connection: keep-alive\r\n"
6682 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166683 };
6684
6685 MockRead data_reads2[] = {
6686 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6687 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6688 MockRead("Content-Length: 10\r\n\r\n"),
6689 MockRead(SYNCHRONOUS, ERR_FAILED),
6690 };
6691
6692 // After the challenge above, the transaction will be restarted using the
6693 // identity supplied by the user (foo, bar) to answer the challenge.
6694 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236695 MockWrite(
6696 "GET / HTTP/1.1\r\n"
6697 "Host: www.example.org\r\n"
6698 "Connection: keep-alive\r\n"
6699 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166700 };
6701
6702 MockRead data_reads3[] = {
6703 MockRead("HTTP/1.0 200 OK\r\n"),
6704 MockRead("Content-Length: 100\r\n\r\n"),
6705 MockRead(SYNCHRONOUS, OK),
6706 };
6707
6708 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6709 data_writes1, arraysize(data_writes1));
6710 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6711 data_writes2, arraysize(data_writes2));
6712 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6713 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076714 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6715 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6716 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166717
6718 TestCompletionCallback callback1;
6719
6720 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6721 EXPECT_EQ(ERR_IO_PENDING, rv);
6722
6723 rv = callback1.WaitForResult();
6724 EXPECT_EQ(OK, rv);
6725
6726 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6727 TestCompletionCallback callback2;
6728 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6729 EXPECT_EQ(ERR_IO_PENDING, rv);
6730 rv = callback2.WaitForResult();
6731 EXPECT_EQ(OK, rv);
6732 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6733
6734 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526735 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166736 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6737
6738 TestCompletionCallback callback3;
6739 rv = trans->RestartWithAuth(
6740 AuthCredentials(kFoo, kBar), callback3.callback());
6741 EXPECT_EQ(ERR_IO_PENDING, rv);
6742 rv = callback3.WaitForResult();
6743 EXPECT_EQ(OK, rv);
6744 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6745
6746 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526747 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166748
6749 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526750 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166751
6752 EXPECT_EQ(100, response->headers->GetContentLength());
6753
[email protected]ea9dc9a2009-09-05 00:43:326754 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556755 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326756}
6757
[email protected]2217aa22013-10-11 03:03:546758
6759// Test the request-challenge-retry sequence for basic auth when there is a
6760// correct identity in the URL, but its use is being suppressed. The identity
6761// from the URL should never be used.
6762TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
6763 HttpRequestInfo request;
6764 request.method = "GET";
bncce36dca22015-04-21 22:11:236765 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546766 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6767
danakj1fd259a02016-04-16 03:17:096768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6769 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:546771
6772 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236773 MockWrite(
6774 "GET / HTTP/1.1\r\n"
6775 "Host: www.example.org\r\n"
6776 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546777 };
6778
6779 MockRead data_reads1[] = {
6780 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6781 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6782 MockRead("Content-Length: 10\r\n\r\n"),
6783 MockRead(SYNCHRONOUS, ERR_FAILED),
6784 };
6785
6786 // After the challenge above, the transaction will be restarted using the
6787 // identity supplied by the user, not the one in the URL, to answer the
6788 // challenge.
6789 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236790 MockWrite(
6791 "GET / HTTP/1.1\r\n"
6792 "Host: www.example.org\r\n"
6793 "Connection: keep-alive\r\n"
6794 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546795 };
6796
6797 MockRead data_reads3[] = {
6798 MockRead("HTTP/1.0 200 OK\r\n"),
6799 MockRead("Content-Length: 100\r\n\r\n"),
6800 MockRead(SYNCHRONOUS, OK),
6801 };
6802
6803 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6804 data_writes1, arraysize(data_writes1));
6805 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6806 data_writes3, arraysize(data_writes3));
6807 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6808 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6809
6810 TestCompletionCallback callback1;
6811 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6812 EXPECT_EQ(ERR_IO_PENDING, rv);
6813 rv = callback1.WaitForResult();
6814 EXPECT_EQ(OK, rv);
6815 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6816
6817 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526818 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:546819 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6820
6821 TestCompletionCallback callback3;
6822 rv = trans->RestartWithAuth(
6823 AuthCredentials(kFoo, kBar), callback3.callback());
6824 EXPECT_EQ(ERR_IO_PENDING, rv);
6825 rv = callback3.WaitForResult();
6826 EXPECT_EQ(OK, rv);
6827 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6828
6829 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526830 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:546831
6832 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526833 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:546834 EXPECT_EQ(100, response->headers->GetContentLength());
6835
6836 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556837 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:546838}
6839
[email protected]f9ee6b52008-11-08 06:46:236840// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:026841TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:096842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:236843
6844 // Transaction 1: authenticate (foo, bar) on MyRealm1
6845 {
[email protected]1c773ea12009-04-28 19:58:426846 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236847 request.method = "GET";
bncce36dca22015-04-21 22:11:236848 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:236849 request.load_flags = 0;
6850
danakj1fd259a02016-04-16 03:17:096851 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506852 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276853
[email protected]f9ee6b52008-11-08 06:46:236854 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236855 MockWrite(
6856 "GET /x/y/z HTTP/1.1\r\n"
6857 "Host: www.example.org\r\n"
6858 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236859 };
6860
6861 MockRead data_reads1[] = {
6862 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6863 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6864 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066865 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236866 };
6867
6868 // Resend with authorization (username=foo, password=bar)
6869 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236870 MockWrite(
6871 "GET /x/y/z HTTP/1.1\r\n"
6872 "Host: www.example.org\r\n"
6873 "Connection: keep-alive\r\n"
6874 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236875 };
6876
6877 // Sever accepts the authorization.
6878 MockRead data_reads2[] = {
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));
[email protected]bb88e1d32013-05-03 23:11:076888 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6889 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236890
[email protected]49639fa2011-12-20 23:22:416891 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236892
[email protected]49639fa2011-12-20 23:22:416893 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426894 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236895
6896 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426897 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236898
[email protected]1c773ea12009-04-28 19:58:426899 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526900 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046901 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236902
[email protected]49639fa2011-12-20 23:22:416903 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236904
[email protected]49639fa2011-12-20 23:22:416905 rv = trans->RestartWithAuth(
6906 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426907 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236908
6909 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426910 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236911
6912 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526913 ASSERT_TRUE(response);
6914 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:236915 EXPECT_EQ(100, response->headers->GetContentLength());
6916 }
6917
6918 // ------------------------------------------------------------------------
6919
6920 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
6921 {
[email protected]1c773ea12009-04-28 19:58:426922 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236923 request.method = "GET";
6924 // Note that Transaction 1 was at /x/y/z, so this is in the same
6925 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:236926 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:236927 request.load_flags = 0;
6928
danakj1fd259a02016-04-16 03:17:096929 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506930 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276931
[email protected]f9ee6b52008-11-08 06:46:236932 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236933 MockWrite(
6934 "GET /x/y/a/b HTTP/1.1\r\n"
6935 "Host: www.example.org\r\n"
6936 "Connection: keep-alive\r\n"
6937 // Send preemptive authorization for MyRealm1
6938 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236939 };
6940
6941 // The server didn't like the preemptive authorization, and
6942 // challenges us for a different realm (MyRealm2).
6943 MockRead data_reads1[] = {
6944 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6945 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
6946 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066947 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236948 };
6949
6950 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
6951 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236952 MockWrite(
6953 "GET /x/y/a/b HTTP/1.1\r\n"
6954 "Host: www.example.org\r\n"
6955 "Connection: keep-alive\r\n"
6956 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236957 };
6958
6959 // Sever accepts the authorization.
6960 MockRead data_reads2[] = {
6961 MockRead("HTTP/1.0 200 OK\r\n"),
6962 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066963 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236964 };
6965
[email protected]31a2bfe2010-02-09 08:03:396966 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6967 data_writes1, arraysize(data_writes1));
6968 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6969 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076970 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6971 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236972
[email protected]49639fa2011-12-20 23:22:416973 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236974
[email protected]49639fa2011-12-20 23:22:416975 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426976 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236977
6978 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426979 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236980
[email protected]1c773ea12009-04-28 19:58:426981 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526982 ASSERT_TRUE(response);
6983 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:046984 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:436985 EXPECT_EQ("http://www.example.org",
6986 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:046987 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:196988 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:236989
[email protected]49639fa2011-12-20 23:22:416990 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236991
[email protected]49639fa2011-12-20 23:22:416992 rv = trans->RestartWithAuth(
6993 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426994 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236995
6996 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426997 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236998
6999 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527000 ASSERT_TRUE(response);
7001 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237002 EXPECT_EQ(100, response->headers->GetContentLength());
7003 }
7004
7005 // ------------------------------------------------------------------------
7006
7007 // Transaction 3: Resend a request in MyRealm's protection space --
7008 // succeed with preemptive authorization.
7009 {
[email protected]1c773ea12009-04-28 19:58:427010 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237011 request.method = "GET";
bncce36dca22015-04-21 22:11:237012 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237013 request.load_flags = 0;
7014
danakj1fd259a02016-04-16 03:17:097015 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507016 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277017
[email protected]f9ee6b52008-11-08 06:46:237018 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237019 MockWrite(
7020 "GET /x/y/z2 HTTP/1.1\r\n"
7021 "Host: www.example.org\r\n"
7022 "Connection: keep-alive\r\n"
7023 // The authorization for MyRealm1 gets sent preemptively
7024 // (since the url is in the same protection space)
7025 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237026 };
7027
7028 // Sever accepts the preemptive authorization
7029 MockRead data_reads1[] = {
7030 MockRead("HTTP/1.0 200 OK\r\n"),
7031 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067032 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237033 };
7034
[email protected]31a2bfe2010-02-09 08:03:397035 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7036 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077037 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237038
[email protected]49639fa2011-12-20 23:22:417039 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237040
[email protected]49639fa2011-12-20 23:22:417041 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427042 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237043
7044 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427045 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237046
[email protected]1c773ea12009-04-28 19:58:427047 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527048 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237049
wezca1070932016-05-26 20:30:527050 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237051 EXPECT_EQ(100, response->headers->GetContentLength());
7052 }
7053
7054 // ------------------------------------------------------------------------
7055
7056 // Transaction 4: request another URL in MyRealm (however the
7057 // url is not known to belong to the protection space, so no pre-auth).
7058 {
[email protected]1c773ea12009-04-28 19:58:427059 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237060 request.method = "GET";
bncce36dca22015-04-21 22:11:237061 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237062 request.load_flags = 0;
7063
danakj1fd259a02016-04-16 03:17:097064 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507065 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277066
[email protected]f9ee6b52008-11-08 06:46:237067 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237068 MockWrite(
7069 "GET /x/1 HTTP/1.1\r\n"
7070 "Host: www.example.org\r\n"
7071 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237072 };
7073
7074 MockRead data_reads1[] = {
7075 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7076 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7077 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067078 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237079 };
7080
7081 // Resend with authorization from MyRealm's cache.
7082 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237083 MockWrite(
7084 "GET /x/1 HTTP/1.1\r\n"
7085 "Host: www.example.org\r\n"
7086 "Connection: keep-alive\r\n"
7087 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237088 };
7089
7090 // Sever accepts the authorization.
7091 MockRead data_reads2[] = {
7092 MockRead("HTTP/1.0 200 OK\r\n"),
7093 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067094 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237095 };
7096
[email protected]31a2bfe2010-02-09 08:03:397097 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7098 data_writes1, arraysize(data_writes1));
7099 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7100 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077101 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7102 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237103
[email protected]49639fa2011-12-20 23:22:417104 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237105
[email protected]49639fa2011-12-20 23:22:417106 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427107 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237108
7109 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427110 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237111
[email protected]0757e7702009-03-27 04:00:227112 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417113 TestCompletionCallback callback2;
7114 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:427115 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:227116 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427117 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:227118 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
7119
[email protected]1c773ea12009-04-28 19:58:427120 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527121 ASSERT_TRUE(response);
7122 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237123 EXPECT_EQ(100, response->headers->GetContentLength());
7124 }
7125
7126 // ------------------------------------------------------------------------
7127
7128 // Transaction 5: request a URL in MyRealm, but the server rejects the
7129 // cached identity. Should invalidate and re-prompt.
7130 {
[email protected]1c773ea12009-04-28 19:58:427131 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237132 request.method = "GET";
bncce36dca22015-04-21 22:11:237133 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237134 request.load_flags = 0;
7135
danakj1fd259a02016-04-16 03:17:097136 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277138
[email protected]f9ee6b52008-11-08 06:46:237139 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237140 MockWrite(
7141 "GET /p/q/t HTTP/1.1\r\n"
7142 "Host: www.example.org\r\n"
7143 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237144 };
7145
7146 MockRead data_reads1[] = {
7147 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7148 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7149 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067150 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237151 };
7152
7153 // Resend with authorization from cache for MyRealm.
7154 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237155 MockWrite(
7156 "GET /p/q/t HTTP/1.1\r\n"
7157 "Host: www.example.org\r\n"
7158 "Connection: keep-alive\r\n"
7159 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237160 };
7161
7162 // Sever rejects the authorization.
7163 MockRead data_reads2[] = {
7164 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7165 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7166 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067167 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237168 };
7169
7170 // At this point we should prompt for new credentials for MyRealm.
7171 // Restart with username=foo3, password=foo4.
7172 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237173 MockWrite(
7174 "GET /p/q/t HTTP/1.1\r\n"
7175 "Host: www.example.org\r\n"
7176 "Connection: keep-alive\r\n"
7177 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237178 };
7179
7180 // Sever accepts the authorization.
7181 MockRead data_reads3[] = {
7182 MockRead("HTTP/1.0 200 OK\r\n"),
7183 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067184 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237185 };
7186
[email protected]31a2bfe2010-02-09 08:03:397187 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7188 data_writes1, arraysize(data_writes1));
7189 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7190 data_writes2, arraysize(data_writes2));
7191 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7192 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077193 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7194 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7195 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237196
[email protected]49639fa2011-12-20 23:22:417197 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237198
[email protected]49639fa2011-12-20 23:22:417199 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427200 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237201
7202 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427203 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237204
[email protected]0757e7702009-03-27 04:00:227205 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417206 TestCompletionCallback callback2;
7207 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:427208 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:227209 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427210 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:227211 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
7212
[email protected]1c773ea12009-04-28 19:58:427213 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527214 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047215 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237216
[email protected]49639fa2011-12-20 23:22:417217 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237218
[email protected]49639fa2011-12-20 23:22:417219 rv = trans->RestartWithAuth(
7220 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:427221 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237222
[email protected]0757e7702009-03-27 04:00:227223 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427224 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237225
7226 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527227 ASSERT_TRUE(response);
7228 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237229 EXPECT_EQ(100, response->headers->GetContentLength());
7230 }
7231}
[email protected]89ceba9a2009-03-21 03:46:067232
[email protected]3c32c5f2010-05-18 15:18:127233// Tests that nonce count increments when multiple auth attempts
7234// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:027235TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447236 HttpAuthHandlerDigest::Factory* digest_factory =
7237 new HttpAuthHandlerDigest::Factory();
7238 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7239 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7240 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077241 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097242 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127243
7244 // Transaction 1: authenticate (foo, bar) on MyRealm1
7245 {
[email protected]3c32c5f2010-05-18 15:18:127246 HttpRequestInfo request;
7247 request.method = "GET";
bncce36dca22015-04-21 22:11:237248 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127249 request.load_flags = 0;
7250
danakj1fd259a02016-04-16 03:17:097251 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507252 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277253
[email protected]3c32c5f2010-05-18 15:18:127254 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237255 MockWrite(
7256 "GET /x/y/z HTTP/1.1\r\n"
7257 "Host: www.example.org\r\n"
7258 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127259 };
7260
7261 MockRead data_reads1[] = {
7262 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7263 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7264 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067265 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127266 };
7267
7268 // Resend with authorization (username=foo, password=bar)
7269 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237270 MockWrite(
7271 "GET /x/y/z HTTP/1.1\r\n"
7272 "Host: www.example.org\r\n"
7273 "Connection: keep-alive\r\n"
7274 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7275 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7276 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7277 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127278 };
7279
7280 // Sever accepts the authorization.
7281 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087282 MockRead("HTTP/1.0 200 OK\r\n"),
7283 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127284 };
7285
7286 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7287 data_writes1, arraysize(data_writes1));
7288 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7289 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077290 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7291 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127292
[email protected]49639fa2011-12-20 23:22:417293 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127294
[email protected]49639fa2011-12-20 23:22:417295 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:127296 EXPECT_EQ(ERR_IO_PENDING, rv);
7297
7298 rv = callback1.WaitForResult();
7299 EXPECT_EQ(OK, rv);
7300
7301 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527302 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047303 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127304
[email protected]49639fa2011-12-20 23:22:417305 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127306
[email protected]49639fa2011-12-20 23:22:417307 rv = trans->RestartWithAuth(
7308 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:127309 EXPECT_EQ(ERR_IO_PENDING, rv);
7310
7311 rv = callback2.WaitForResult();
7312 EXPECT_EQ(OK, rv);
7313
7314 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527315 ASSERT_TRUE(response);
7316 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127317 }
7318
7319 // ------------------------------------------------------------------------
7320
7321 // Transaction 2: Request another resource in digestive's protection space.
7322 // This will preemptively add an Authorization header which should have an
7323 // "nc" value of 2 (as compared to 1 in the first use.
7324 {
[email protected]3c32c5f2010-05-18 15:18:127325 HttpRequestInfo request;
7326 request.method = "GET";
7327 // Note that Transaction 1 was at /x/y/z, so this is in the same
7328 // protection space as digest.
bncce36dca22015-04-21 22:11:237329 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127330 request.load_flags = 0;
7331
danakj1fd259a02016-04-16 03:17:097332 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277334
[email protected]3c32c5f2010-05-18 15:18:127335 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237336 MockWrite(
7337 "GET /x/y/a/b HTTP/1.1\r\n"
7338 "Host: www.example.org\r\n"
7339 "Connection: keep-alive\r\n"
7340 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7341 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7342 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7343 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127344 };
7345
7346 // Sever accepts the authorization.
7347 MockRead data_reads1[] = {
7348 MockRead("HTTP/1.0 200 OK\r\n"),
7349 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067350 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127351 };
7352
7353 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7354 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077355 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127356
[email protected]49639fa2011-12-20 23:22:417357 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127358
[email protected]49639fa2011-12-20 23:22:417359 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:127360 EXPECT_EQ(ERR_IO_PENDING, rv);
7361
7362 rv = callback1.WaitForResult();
7363 EXPECT_EQ(OK, rv);
7364
7365 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527366 ASSERT_TRUE(response);
7367 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127368 }
7369}
7370
[email protected]89ceba9a2009-03-21 03:46:067371// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:027372TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067373 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097374 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7375 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:417376 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:067377
7378 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:067379 trans->read_buf_ = new IOBuffer(15);
7380 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:207381 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067382
7383 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:147384 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:577385 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087386 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577387 response->response_time = base::Time::Now();
7388 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067389
7390 { // Setup state for response_.vary_data
7391 HttpRequestInfo request;
7392 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7393 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277394 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437395 request.extra_headers.SetHeader("Foo", "1");
7396 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507397 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067398 }
7399
7400 // Cause the above state to be reset.
7401 trans->ResetStateForRestart();
7402
7403 // Verify that the state that needed to be reset, has been reset.
wezca1070932016-05-26 20:30:527404 EXPECT_FALSE(trans->read_buf_);
[email protected]89ceba9a2009-03-21 03:46:067405 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:207406 EXPECT_TRUE(trans->request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527407 EXPECT_FALSE(response->auth_challenge);
7408 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047409 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087410 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577411 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067412}
7413
[email protected]bacff652009-03-31 17:50:337414// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:027415TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337416 HttpRequestInfo request;
7417 request.method = "GET";
bncce36dca22015-04-21 22:11:237418 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337419 request.load_flags = 0;
7420
danakj1fd259a02016-04-16 03:17:097421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7422 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417423 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277424
[email protected]bacff652009-03-31 17:50:337425 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237426 MockWrite(
7427 "GET / HTTP/1.1\r\n"
7428 "Host: www.example.org\r\n"
7429 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337430 };
7431
7432 MockRead data_reads[] = {
7433 MockRead("HTTP/1.0 200 OK\r\n"),
7434 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7435 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067436 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337437 };
7438
[email protected]5ecc992a42009-11-11 01:41:597439 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397440 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7441 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067442 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7443 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337444
[email protected]bb88e1d32013-05-03 23:11:077445 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7446 session_deps_.socket_factory->AddSocketDataProvider(&data);
7447 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337449
[email protected]49639fa2011-12-20 23:22:417450 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337451
[email protected]49639fa2011-12-20 23:22:417452 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337453 EXPECT_EQ(ERR_IO_PENDING, rv);
7454
7455 rv = callback.WaitForResult();
7456 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7457
[email protected]49639fa2011-12-20 23:22:417458 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337459 EXPECT_EQ(ERR_IO_PENDING, rv);
7460
7461 rv = callback.WaitForResult();
7462 EXPECT_EQ(OK, rv);
7463
7464 const HttpResponseInfo* response = trans->GetResponseInfo();
7465
wezca1070932016-05-26 20:30:527466 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337467 EXPECT_EQ(100, response->headers->GetContentLength());
7468}
7469
7470// Test HTTPS connections to a site with a bad certificate, going through a
7471// proxy
[email protected]23e482282013-06-14 16:08:027472TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037473 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337474
7475 HttpRequestInfo request;
7476 request.method = "GET";
bncce36dca22015-04-21 22:11:237477 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337478 request.load_flags = 0;
7479
7480 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177481 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7482 "Host: www.example.org:443\r\n"
7483 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337484 };
7485
7486 MockRead proxy_reads[] = {
7487 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067488 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337489 };
7490
7491 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177492 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7493 "Host: www.example.org:443\r\n"
7494 "Proxy-Connection: keep-alive\r\n\r\n"),
7495 MockWrite("GET / HTTP/1.1\r\n"
7496 "Host: www.example.org\r\n"
7497 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337498 };
7499
7500 MockRead data_reads[] = {
7501 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7502 MockRead("HTTP/1.0 200 OK\r\n"),
7503 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7504 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067505 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337506 };
7507
[email protected]31a2bfe2010-02-09 08:03:397508 StaticSocketDataProvider ssl_bad_certificate(
7509 proxy_reads, arraysize(proxy_reads),
7510 proxy_writes, arraysize(proxy_writes));
7511 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7512 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067513 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7514 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337515
[email protected]bb88e1d32013-05-03 23:11:077516 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7517 session_deps_.socket_factory->AddSocketDataProvider(&data);
7518 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7519 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337520
[email protected]49639fa2011-12-20 23:22:417521 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337522
7523 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077524 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337525
danakj1fd259a02016-04-16 03:17:097526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7527 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417528 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:337529
[email protected]49639fa2011-12-20 23:22:417530 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337531 EXPECT_EQ(ERR_IO_PENDING, rv);
7532
7533 rv = callback.WaitForResult();
7534 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7535
[email protected]49639fa2011-12-20 23:22:417536 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337537 EXPECT_EQ(ERR_IO_PENDING, rv);
7538
7539 rv = callback.WaitForResult();
7540 EXPECT_EQ(OK, rv);
7541
7542 const HttpResponseInfo* response = trans->GetResponseInfo();
7543
wezca1070932016-05-26 20:30:527544 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337545 EXPECT_EQ(100, response->headers->GetContentLength());
7546 }
7547}
7548
[email protected]2df19bb2010-08-25 20:13:467549
7550// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:027551TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037552 session_deps_.proxy_service =
7553 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517554 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077555 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467556
7557 HttpRequestInfo request;
7558 request.method = "GET";
bncce36dca22015-04-21 22:11:237559 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467560 request.load_flags = 0;
7561
7562 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177563 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7564 "Host: www.example.org:443\r\n"
7565 "Proxy-Connection: keep-alive\r\n\r\n"),
7566 MockWrite("GET / HTTP/1.1\r\n"
7567 "Host: www.example.org\r\n"
7568 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467569 };
7570
7571 MockRead data_reads[] = {
7572 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7573 MockRead("HTTP/1.1 200 OK\r\n"),
7574 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7575 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067576 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467577 };
7578
7579 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7580 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067581 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7582 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467583
[email protected]bb88e1d32013-05-03 23:11:077584 session_deps_.socket_factory->AddSocketDataProvider(&data);
7585 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7586 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467587
[email protected]49639fa2011-12-20 23:22:417588 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467589
danakj1fd259a02016-04-16 03:17:097590 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7591 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417592 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467593
[email protected]49639fa2011-12-20 23:22:417594 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467595 EXPECT_EQ(ERR_IO_PENDING, rv);
7596
7597 rv = callback.WaitForResult();
7598 EXPECT_EQ(OK, rv);
7599 const HttpResponseInfo* response = trans->GetResponseInfo();
7600
wezca1070932016-05-26 20:30:527601 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467602
7603 EXPECT_TRUE(response->headers->IsKeepAlive());
7604 EXPECT_EQ(200, response->headers->response_code());
7605 EXPECT_EQ(100, response->headers->GetContentLength());
7606 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207607
7608 LoadTimingInfo load_timing_info;
7609 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7610 TestLoadTimingNotReusedWithPac(load_timing_info,
7611 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467612}
7613
[email protected]511f6f52010-12-17 03:58:297614// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027615TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037616 session_deps_.proxy_service =
7617 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517618 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077619 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297620
7621 HttpRequestInfo request;
7622 request.method = "GET";
bncce36dca22015-04-21 22:11:237623 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297624 request.load_flags = 0;
7625
7626 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177627 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7628 "Host: www.example.org:443\r\n"
7629 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297630 };
7631
7632 MockRead data_reads[] = {
7633 MockRead("HTTP/1.1 302 Redirect\r\n"),
7634 MockRead("Location: http://login.example.com/\r\n"),
7635 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067636 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297637 };
7638
7639 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7640 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067641 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297642
[email protected]bb88e1d32013-05-03 23:11:077643 session_deps_.socket_factory->AddSocketDataProvider(&data);
7644 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297645
[email protected]49639fa2011-12-20 23:22:417646 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297647
danakj1fd259a02016-04-16 03:17:097648 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7649 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417650 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297651
[email protected]49639fa2011-12-20 23:22:417652 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297653 EXPECT_EQ(ERR_IO_PENDING, rv);
7654
7655 rv = callback.WaitForResult();
7656 EXPECT_EQ(OK, rv);
7657 const HttpResponseInfo* response = trans->GetResponseInfo();
7658
wezca1070932016-05-26 20:30:527659 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297660
7661 EXPECT_EQ(302, response->headers->response_code());
7662 std::string url;
7663 EXPECT_TRUE(response->headers->IsRedirect(&url));
7664 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207665
7666 // In the case of redirects from proxies, HttpNetworkTransaction returns
7667 // timing for the proxy connection instead of the connection to the host,
7668 // and no send / receive times.
7669 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7670 LoadTimingInfo load_timing_info;
7671 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7672
7673 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:297674 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207675
7676 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7677 EXPECT_LE(load_timing_info.proxy_resolve_start,
7678 load_timing_info.proxy_resolve_end);
7679 EXPECT_LE(load_timing_info.proxy_resolve_end,
7680 load_timing_info.connect_timing.connect_start);
7681 ExpectConnectTimingHasTimes(
7682 load_timing_info.connect_timing,
7683 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7684
7685 EXPECT_TRUE(load_timing_info.send_start.is_null());
7686 EXPECT_TRUE(load_timing_info.send_end.is_null());
7687 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297688}
7689
7690// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027691TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037692 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297693
7694 HttpRequestInfo request;
7695 request.method = "GET";
bncce36dca22015-04-21 22:11:237696 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297697 request.load_flags = 0;
7698
danakj1fd259a02016-04-16 03:17:097699 std::unique_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237700 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097701 std::unique_ptr<SpdySerializedFrame> goaway(
[email protected]c10b20852013-05-15 21:29:207702 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297703 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137704 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
7705 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297706 };
7707
7708 static const char* const kExtraHeaders[] = {
7709 "location",
7710 "http://login.example.com/",
7711 };
danakj1fd259a02016-04-16 03:17:097712 std::unique_ptr<SpdySerializedFrame> resp(
7713 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
7714 arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297715 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137716 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297717 };
7718
rch8e6c6c42015-05-01 14:05:137719 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7720 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067721 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387722 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297723
[email protected]bb88e1d32013-05-03 23:11:077724 session_deps_.socket_factory->AddSocketDataProvider(&data);
7725 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297726
[email protected]49639fa2011-12-20 23:22:417727 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297728
danakj1fd259a02016-04-16 03:17:097729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7730 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417731 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297732
[email protected]49639fa2011-12-20 23:22:417733 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297734 EXPECT_EQ(ERR_IO_PENDING, rv);
7735
7736 rv = callback.WaitForResult();
7737 EXPECT_EQ(OK, rv);
7738 const HttpResponseInfo* response = trans->GetResponseInfo();
7739
wezca1070932016-05-26 20:30:527740 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297741
7742 EXPECT_EQ(302, response->headers->response_code());
7743 std::string url;
7744 EXPECT_TRUE(response->headers->IsRedirect(&url));
7745 EXPECT_EQ("http://login.example.com/", url);
7746}
7747
[email protected]4eddbc732012-08-09 05:40:177748// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027749TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177750 ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037751 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297752
7753 HttpRequestInfo request;
7754 request.method = "GET";
bncce36dca22015-04-21 22:11:237755 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297756 request.load_flags = 0;
7757
7758 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177759 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7760 "Host: www.example.org:443\r\n"
7761 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297762 };
7763
7764 MockRead data_reads[] = {
7765 MockRead("HTTP/1.1 404 Not Found\r\n"),
7766 MockRead("Content-Length: 23\r\n\r\n"),
7767 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067768 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297769 };
7770
7771 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7772 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067773 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297774
[email protected]bb88e1d32013-05-03 23:11:077775 session_deps_.socket_factory->AddSocketDataProvider(&data);
7776 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297777
[email protected]49639fa2011-12-20 23:22:417778 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297779
danakj1fd259a02016-04-16 03:17:097780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7781 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417782 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297783
[email protected]49639fa2011-12-20 23:22:417784 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297785 EXPECT_EQ(ERR_IO_PENDING, rv);
7786
7787 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177788 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297789
ttuttle960fcbf2016-04-19 13:26:327790 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297791}
7792
[email protected]4eddbc732012-08-09 05:40:177793// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027794TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177795 ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037796 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297797
7798 HttpRequestInfo request;
7799 request.method = "GET";
bncce36dca22015-04-21 22:11:237800 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297801 request.load_flags = 0;
7802
danakj1fd259a02016-04-16 03:17:097803 std::unique_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237804 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097805 std::unique_ptr<SpdySerializedFrame> rst(
[email protected]c10b20852013-05-15 21:29:207806 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297807 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137808 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:297809 };
7810
7811 static const char* const kExtraHeaders[] = {
7812 "location",
7813 "http://login.example.com/",
7814 };
danakj1fd259a02016-04-16 03:17:097815 std::unique_ptr<SpdySerializedFrame> resp(
7816 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
7817 arraysize(kExtraHeaders) / 2, 1));
7818 std::unique_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame(
bncb03b1092016-04-06 11:19:557819 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297820 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137821 CreateMockRead(*resp.get(), 1),
7822 CreateMockRead(*body.get(), 2),
7823 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297824 };
7825
rch8e6c6c42015-05-01 14:05:137826 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7827 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067828 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387829 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297830
[email protected]bb88e1d32013-05-03 23:11:077831 session_deps_.socket_factory->AddSocketDataProvider(&data);
7832 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297833
[email protected]49639fa2011-12-20 23:22:417834 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297835
danakj1fd259a02016-04-16 03:17:097836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7837 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417838 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297839
[email protected]49639fa2011-12-20 23:22:417840 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297841 EXPECT_EQ(ERR_IO_PENDING, rv);
7842
7843 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177844 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297845
ttuttle960fcbf2016-04-19 13:26:327846 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297847}
7848
[email protected]0c5fb722012-02-28 11:50:357849// Test the request-challenge-retry sequence for basic auth, through
7850// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:027851TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:357852 HttpRequestInfo request;
7853 request.method = "GET";
bncce36dca22015-04-21 22:11:237854 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:357855 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:297856 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:357857
7858 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037859 session_deps_.proxy_service =
7860 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517861 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077862 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:097863 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:357864
7865 // Since we have proxy, should try to establish tunnel.
danakj1fd259a02016-04-16 03:17:097866 std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237867 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097868 std::unique_ptr<SpdySerializedFrame> rst(
[email protected]c10b20852013-05-15 21:29:207869 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
rdsmithebb50aa2015-11-12 03:44:387870 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:357871
7872 // After calling trans->RestartWithAuth(), this is the request we should
7873 // be issuing -- the final header line contains the credentials.
7874 const char* const kAuthCredentials[] = {
7875 "proxy-authorization", "Basic Zm9vOmJhcg==",
7876 };
danakj1fd259a02016-04-16 03:17:097877 std::unique_ptr<SpdySerializedFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:347878 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:237879 HostPortPair("www.example.org", 443)));
7880 // fetch https://www.example.org/ via HTTP
7881 const char get[] =
7882 "GET / HTTP/1.1\r\n"
7883 "Host: www.example.org\r\n"
7884 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:097885 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:027886 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:357887
7888 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137889 CreateMockWrite(*req, 0, ASYNC),
7890 CreateMockWrite(*rst, 2, ASYNC),
7891 CreateMockWrite(*connect2, 3),
7892 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:357893 };
7894
7895 // The proxy responds to the connect with a 407, using a persistent
7896 // connection.
thestig9d3bb0c2015-01-24 00:49:517897 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:357898 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:357899 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
7900 };
danakj1fd259a02016-04-16 03:17:097901 std::unique_ptr<SpdySerializedFrame> conn_auth_resp(
bncb03b1092016-04-06 11:19:557902 spdy_util_.ConstructSpdySynReplyError(kAuthStatus, kAuthChallenge,
7903 arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:357904
danakj1fd259a02016-04-16 03:17:097905 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:027906 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:357907 const char resp[] = "HTTP/1.1 200 OK\r\n"
7908 "Content-Length: 5\r\n\r\n";
7909
danakj1fd259a02016-04-16 03:17:097910 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:027911 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
danakj1fd259a02016-04-16 03:17:097912 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:027913 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:357914 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137915 CreateMockRead(*conn_auth_resp, 1, ASYNC),
7916 CreateMockRead(*conn_resp, 4, ASYNC),
7917 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
7918 CreateMockRead(*wrapped_body, 7, ASYNC),
7919 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:357920 };
7921
rch8e6c6c42015-05-01 14:05:137922 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7923 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077924 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:357925 // Negotiate SPDY to the proxy
7926 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387927 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077928 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:357929 // Vanilla SSL to the server
7930 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077931 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:357932
7933 TestCompletionCallback callback1;
7934
danakj1fd259a02016-04-16 03:17:097935 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507936 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:357937
7938 int rv = trans->Start(&request, callback1.callback(), log.bound());
7939 EXPECT_EQ(ERR_IO_PENDING, rv);
7940
7941 rv = callback1.WaitForResult();
7942 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:467943 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:357944 log.GetEntries(&entries);
7945 size_t pos = ExpectLogContainsSomewhere(
7946 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
7947 NetLog::PHASE_NONE);
7948 ExpectLogContainsSomewhere(
7949 entries, pos,
7950 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
7951 NetLog::PHASE_NONE);
7952
7953 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527954 ASSERT_TRUE(response);
7955 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:357956 EXPECT_EQ(407, response->headers->response_code());
7957 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:527958 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:437959 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:357960
7961 TestCompletionCallback callback2;
7962
7963 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
7964 callback2.callback());
7965 EXPECT_EQ(ERR_IO_PENDING, rv);
7966
7967 rv = callback2.WaitForResult();
7968 EXPECT_EQ(OK, rv);
7969
7970 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527971 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:357972
7973 EXPECT_TRUE(response->headers->IsKeepAlive());
7974 EXPECT_EQ(200, response->headers->response_code());
7975 EXPECT_EQ(5, response->headers->GetContentLength());
7976 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7977
7978 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:527979 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:357980
[email protected]029c83b62013-01-24 05:28:207981 LoadTimingInfo load_timing_info;
7982 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7983 TestLoadTimingNotReusedWithPac(load_timing_info,
7984 CONNECT_TIMING_HAS_SSL_TIMES);
7985
[email protected]0c5fb722012-02-28 11:50:357986 trans.reset();
7987 session->CloseAllConnections();
7988}
7989
[email protected]7c6f7ba2012-04-03 04:09:297990// Test that an explicitly trusted SPDY proxy can push a resource from an
7991// origin that is different from that of its associated resource.
tbansal28e68f82016-02-04 02:56:157992TEST_P(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
7993 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:097994 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:157995 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
7996 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:297997 HttpRequestInfo request;
7998 HttpRequestInfo push_request;
7999
[email protected]7c6f7ba2012-04-03 04:09:298000 request.method = "GET";
bncce36dca22015-04-21 22:11:238001 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298002 push_request.method = "GET";
8003 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8004
tbansal28e68f82016-02-04 02:56:158005 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038006 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158007 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518008 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078009 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508010
tbansal28e68f82016-02-04 02:56:158011 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:508012
danakj1fd259a02016-04-16 03:17:098013 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298014
danakj1fd259a02016-04-16 03:17:098015 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:498016 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:298017
8018 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:138019 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298020 };
8021
danakj1fd259a02016-04-16 03:17:098022 std::unique_ptr<SpdySerializedFrame> stream1_reply(
bncb03b1092016-04-06 11:19:558023 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298024
danakj1fd259a02016-04-16 03:17:098025 std::unique_ptr<SpdySerializedFrame> stream1_body(
bncb03b1092016-04-06 11:19:558026 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298027
danakj1fd259a02016-04-16 03:17:098028 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558029 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438030 const char kPushedData[] = "pushed";
danakj1fd259a02016-04-16 03:17:098031 std::unique_ptr<SpdySerializedFrame> stream2_body(
bncb03b1092016-04-06 11:19:558032 spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
8033 true));
[email protected]7c6f7ba2012-04-03 04:09:298034
8035 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:138036 CreateMockRead(*stream1_reply, 1, ASYNC),
8037 CreateMockRead(*stream2_syn, 2, ASYNC),
8038 CreateMockRead(*stream1_body, 3, ASYNC),
8039 CreateMockRead(*stream2_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598040 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298041 };
8042
rch8e6c6c42015-05-01 14:05:138043 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8044 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078045 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298046 // Negotiate SPDY to the proxy
8047 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:388048 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:078049 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298050
danakj1fd259a02016-04-16 03:17:098051 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508052 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:298053 TestCompletionCallback callback;
8054 int rv = trans->Start(&request, callback.callback(), log.bound());
8055 EXPECT_EQ(ERR_IO_PENDING, rv);
8056
8057 rv = callback.WaitForResult();
8058 EXPECT_EQ(OK, rv);
8059 const HttpResponseInfo* response = trans->GetResponseInfo();
8060
danakj1fd259a02016-04-16 03:17:098061 std::unique_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:508062 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8063 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:298064 EXPECT_EQ(ERR_IO_PENDING, rv);
8065
8066 rv = callback.WaitForResult();
8067 EXPECT_EQ(OK, rv);
8068 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8069
wezca1070932016-05-26 20:30:528070 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298071 EXPECT_TRUE(response->headers->IsKeepAlive());
8072
8073 EXPECT_EQ(200, response->headers->response_code());
8074 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8075
8076 std::string response_data;
8077 rv = ReadTransaction(trans.get(), &response_data);
8078 EXPECT_EQ(OK, rv);
8079 EXPECT_EQ("hello!", response_data);
8080
[email protected]029c83b62013-01-24 05:28:208081 LoadTimingInfo load_timing_info;
8082 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8083 TestLoadTimingNotReusedWithPac(load_timing_info,
8084 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8085
[email protected]7c6f7ba2012-04-03 04:09:298086 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528087 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298088 EXPECT_EQ(200, push_response->headers->response_code());
8089
8090 rv = ReadTransaction(push_trans.get(), &response_data);
8091 EXPECT_EQ(OK, rv);
8092 EXPECT_EQ("pushed", response_data);
8093
[email protected]029c83b62013-01-24 05:28:208094 LoadTimingInfo push_load_timing_info;
8095 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8096 TestLoadTimingReusedWithPac(push_load_timing_info);
8097 // The transactions should share a socket ID, despite being for different
8098 // origins.
8099 EXPECT_EQ(load_timing_info.socket_log_id,
8100 push_load_timing_info.socket_log_id);
8101
[email protected]7c6f7ba2012-04-03 04:09:298102 trans.reset();
8103 push_trans.reset();
8104 session->CloseAllConnections();
8105}
8106
[email protected]8c843192012-04-05 07:15:008107// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:028108TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158109 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098110 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158111 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8112 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008113 HttpRequestInfo request;
8114
8115 request.method = "GET";
bncce36dca22015-04-21 22:11:238116 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008117
tbansal28e68f82016-02-04 02:56:158118 session_deps_.proxy_service =
8119 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518120 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078121 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508122
8123 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158124 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:508125
danakj1fd259a02016-04-16 03:17:098126 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008127
danakj1fd259a02016-04-16 03:17:098128 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:498129 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:008130
danakj1fd259a02016-04-16 03:17:098131 std::unique_ptr<SpdySerializedFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:208132 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008133
8134 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:138135 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:008136 };
8137
danakj1fd259a02016-04-16 03:17:098138 std::unique_ptr<SpdySerializedFrame> stream1_reply(
bncb03b1092016-04-06 11:19:558139 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008140
danakj1fd259a02016-04-16 03:17:098141 std::unique_ptr<SpdySerializedFrame> stream1_body(
bncb03b1092016-04-06 11:19:558142 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:008143
danakj1fd259a02016-04-16 03:17:098144 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558145 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008146
8147 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:138148 CreateMockRead(*stream1_reply, 1, ASYNC),
8149 CreateMockRead(*stream2_syn, 2, ASYNC),
8150 CreateMockRead(*stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598151 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008152 };
8153
rch8e6c6c42015-05-01 14:05:138154 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8155 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078156 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008157 // Negotiate SPDY to the proxy
8158 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:388159 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:078160 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008161
danakj1fd259a02016-04-16 03:17:098162 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508163 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:008164 TestCompletionCallback callback;
8165 int rv = trans->Start(&request, callback.callback(), log.bound());
8166 EXPECT_EQ(ERR_IO_PENDING, rv);
8167
8168 rv = callback.WaitForResult();
8169 EXPECT_EQ(OK, rv);
8170 const HttpResponseInfo* response = trans->GetResponseInfo();
8171
wezca1070932016-05-26 20:30:528172 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008173 EXPECT_TRUE(response->headers->IsKeepAlive());
8174
8175 EXPECT_EQ(200, response->headers->response_code());
8176 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8177
8178 std::string response_data;
8179 rv = ReadTransaction(trans.get(), &response_data);
8180 EXPECT_EQ(OK, rv);
8181 EXPECT_EQ("hello!", response_data);
8182
8183 trans.reset();
8184 session->CloseAllConnections();
8185}
8186
tbansal8ef1d3e2016-02-03 04:05:428187// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8188// resources.
8189TEST_P(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158190 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098191 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158192 proxy_delegate->set_trusted_spdy_proxy(
8193 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8194
tbansal8ef1d3e2016-02-03 04:05:428195 HttpRequestInfo request;
8196
8197 request.method = "GET";
8198 request.url = GURL("http://www.example.org/");
8199
8200 // Configure against https proxy server "myproxy:70".
8201 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8202 BoundTestNetLog log;
8203 session_deps_.net_log = log.bound().net_log();
8204
8205 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158206 session_deps_.proxy_delegate.reset(proxy_delegate.release());
tbansal8ef1d3e2016-02-03 04:05:428207
danakj1fd259a02016-04-16 03:17:098208 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428209
danakj1fd259a02016-04-16 03:17:098210 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:498211 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
tbansal8ef1d3e2016-02-03 04:05:428212
8213 MockWrite spdy_writes[] = {
8214 CreateMockWrite(*stream1_syn, 0, ASYNC),
8215 };
8216
danakj1fd259a02016-04-16 03:17:098217 std::unique_ptr<SpdySerializedFrame> stream1_reply(
tbansal8ef1d3e2016-02-03 04:05:428218 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
8219
danakj1fd259a02016-04-16 03:17:098220 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498221 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8222
danakj1fd259a02016-04-16 03:17:098223 std::unique_ptr<SpdySerializedFrame> stream1_body(
tbansal8ef1d3e2016-02-03 04:05:428224 spdy_util_.ConstructSpdyBodyFrame(1, true));
8225
danakj1fd259a02016-04-16 03:17:098226 std::unique_ptr<SpdySerializedFrame> stream2_reply(
tbansal8ef1d3e2016-02-03 04:05:428227 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
8228
danakj1fd259a02016-04-16 03:17:098229 std::unique_ptr<SpdySerializedFrame> stream2_body(
tbansal8ef1d3e2016-02-03 04:05:428230 spdy_util_.ConstructSpdyBodyFrame(1, true));
8231
8232 MockRead spdy_reads[] = {
8233 CreateMockRead(*stream1_reply, 1, ASYNC),
8234 CreateMockRead(*stream2_syn, 2, ASYNC),
8235 CreateMockRead(*stream1_body, 3, ASYNC),
8236 CreateMockRead(*stream2_body, 4, ASYNC),
8237 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
8238 };
8239
8240 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8241 arraysize(spdy_writes));
8242 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8243 // Negotiate SPDY to the proxy
8244 SSLSocketDataProvider proxy(ASYNC, OK);
8245 proxy.SetNextProto(GetProtocol());
8246 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8247
danakj1fd259a02016-04-16 03:17:098248 std::unique_ptr<HttpTransaction> trans(
tbansal8ef1d3e2016-02-03 04:05:428249 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8250 TestCompletionCallback callback;
8251 int rv = trans->Start(&request, callback.callback(), log.bound());
8252 EXPECT_EQ(ERR_IO_PENDING, rv);
8253
8254 rv = callback.WaitForResult();
8255 EXPECT_EQ(OK, rv);
8256 const HttpResponseInfo* response = trans->GetResponseInfo();
8257
wezca1070932016-05-26 20:30:528258 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428259 EXPECT_TRUE(response->headers->IsKeepAlive());
8260
8261 EXPECT_EQ(200, response->headers->response_code());
8262 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8263
8264 std::string response_data;
8265 rv = ReadTransaction(trans.get(), &response_data);
8266 EXPECT_EQ(OK, rv);
8267 EXPECT_EQ("hello!", response_data);
8268
8269 trans.reset();
8270 session->CloseAllConnections();
8271}
8272
[email protected]2df19bb2010-08-25 20:13:468273// Test HTTPS connections to a site with a bad certificate, going through an
8274// HTTPS proxy
[email protected]23e482282013-06-14 16:08:028275TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038276 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468277
8278 HttpRequestInfo request;
8279 request.method = "GET";
bncce36dca22015-04-21 22:11:238280 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468281 request.load_flags = 0;
8282
8283 // Attempt to fetch the URL from a server with a bad cert
8284 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178285 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8286 "Host: www.example.org:443\r\n"
8287 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468288 };
8289
8290 MockRead bad_cert_reads[] = {
8291 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068292 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468293 };
8294
8295 // Attempt to fetch the URL with a good cert
8296 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178297 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8298 "Host: www.example.org:443\r\n"
8299 "Proxy-Connection: keep-alive\r\n\r\n"),
8300 MockWrite("GET / HTTP/1.1\r\n"
8301 "Host: www.example.org\r\n"
8302 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468303 };
8304
8305 MockRead good_cert_reads[] = {
8306 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8307 MockRead("HTTP/1.0 200 OK\r\n"),
8308 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8309 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068310 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468311 };
8312
8313 StaticSocketDataProvider ssl_bad_certificate(
8314 bad_cert_reads, arraysize(bad_cert_reads),
8315 bad_cert_writes, arraysize(bad_cert_writes));
8316 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8317 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068318 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8319 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468320
8321 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078322 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8323 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468325
8326 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8328 session_deps_.socket_factory->AddSocketDataProvider(&data);
8329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468330
[email protected]49639fa2011-12-20 23:22:418331 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468332
danakj1fd259a02016-04-16 03:17:098333 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8334 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418335 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:468336
[email protected]49639fa2011-12-20 23:22:418337 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:468338 EXPECT_EQ(ERR_IO_PENDING, rv);
8339
8340 rv = callback.WaitForResult();
8341 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
8342
[email protected]49639fa2011-12-20 23:22:418343 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:468344 EXPECT_EQ(ERR_IO_PENDING, rv);
8345
8346 rv = callback.WaitForResult();
8347 EXPECT_EQ(OK, rv);
8348
8349 const HttpResponseInfo* response = trans->GetResponseInfo();
8350
wezca1070932016-05-26 20:30:528351 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468352 EXPECT_EQ(100, response->headers->GetContentLength());
8353}
8354
[email protected]23e482282013-06-14 16:08:028355TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428356 HttpRequestInfo request;
8357 request.method = "GET";
bncce36dca22015-04-21 22:11:238358 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438359 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8360 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428361
danakj1fd259a02016-04-16 03:17:098362 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8363 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278365
[email protected]1c773ea12009-04-28 19:58:428366 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238367 MockWrite(
8368 "GET / HTTP/1.1\r\n"
8369 "Host: www.example.org\r\n"
8370 "Connection: keep-alive\r\n"
8371 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428372 };
8373
8374 // Lastly, the server responds with the actual content.
8375 MockRead data_reads[] = {
8376 MockRead("HTTP/1.0 200 OK\r\n"),
8377 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8378 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068379 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428380 };
8381
[email protected]31a2bfe2010-02-09 08:03:398382 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8383 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078384 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428385
[email protected]49639fa2011-12-20 23:22:418386 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428387
[email protected]49639fa2011-12-20 23:22:418388 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428389 EXPECT_EQ(ERR_IO_PENDING, rv);
8390
8391 rv = callback.WaitForResult();
8392 EXPECT_EQ(OK, rv);
8393}
8394
[email protected]23e482282013-06-14 16:08:028395TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298396 HttpRequestInfo request;
8397 request.method = "GET";
bncce36dca22015-04-21 22:11:238398 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298399 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8400 "Chromium Ultra Awesome X Edition");
8401
rdsmith82957ad2015-09-16 19:42:038402 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098403 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8404 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278406
[email protected]da81f132010-08-18 23:39:298407 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178408 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8409 "Host: www.example.org:443\r\n"
8410 "Proxy-Connection: keep-alive\r\n"
8411 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298412 };
8413 MockRead data_reads[] = {
8414 // Return an error, so the transaction stops here (this test isn't
8415 // interested in the rest).
8416 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8417 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8418 MockRead("Proxy-Connection: close\r\n\r\n"),
8419 };
8420
8421 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8422 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078423 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298424
[email protected]49639fa2011-12-20 23:22:418425 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298426
[email protected]49639fa2011-12-20 23:22:418427 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:298428 EXPECT_EQ(ERR_IO_PENDING, rv);
8429
8430 rv = callback.WaitForResult();
8431 EXPECT_EQ(OK, rv);
8432}
8433
[email protected]23e482282013-06-14 16:08:028434TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428435 HttpRequestInfo request;
8436 request.method = "GET";
bncce36dca22015-04-21 22:11:238437 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428438 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:168439 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8440 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428441
danakj1fd259a02016-04-16 03:17:098442 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8443 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418444 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278445
[email protected]1c773ea12009-04-28 19:58:428446 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238447 MockWrite(
8448 "GET / HTTP/1.1\r\n"
8449 "Host: www.example.org\r\n"
8450 "Connection: keep-alive\r\n"
8451 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428452 };
8453
8454 // Lastly, the server responds with the actual content.
8455 MockRead data_reads[] = {
8456 MockRead("HTTP/1.0 200 OK\r\n"),
8457 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8458 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068459 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428460 };
8461
[email protected]31a2bfe2010-02-09 08:03:398462 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8463 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078464 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428465
[email protected]49639fa2011-12-20 23:22:418466 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428467
[email protected]49639fa2011-12-20 23:22:418468 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428469 EXPECT_EQ(ERR_IO_PENDING, rv);
8470
8471 rv = callback.WaitForResult();
8472 EXPECT_EQ(OK, rv);
8473}
8474
[email protected]23e482282013-06-14 16:08:028475TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428476 HttpRequestInfo request;
8477 request.method = "POST";
bncce36dca22015-04-21 22:11:238478 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428479
danakj1fd259a02016-04-16 03:17:098480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8481 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418482 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278483
[email protected]1c773ea12009-04-28 19:58:428484 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238485 MockWrite(
8486 "POST / HTTP/1.1\r\n"
8487 "Host: www.example.org\r\n"
8488 "Connection: keep-alive\r\n"
8489 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428490 };
8491
8492 // Lastly, the server responds with the actual content.
8493 MockRead data_reads[] = {
8494 MockRead("HTTP/1.0 200 OK\r\n"),
8495 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8496 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068497 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428498 };
8499
[email protected]31a2bfe2010-02-09 08:03:398500 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8501 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078502 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428503
[email protected]49639fa2011-12-20 23:22:418504 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428505
[email protected]49639fa2011-12-20 23:22:418506 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428507 EXPECT_EQ(ERR_IO_PENDING, rv);
8508
8509 rv = callback.WaitForResult();
8510 EXPECT_EQ(OK, rv);
8511}
8512
[email protected]23e482282013-06-14 16:08:028513TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428514 HttpRequestInfo request;
8515 request.method = "PUT";
bncce36dca22015-04-21 22:11:238516 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428517
danakj1fd259a02016-04-16 03:17:098518 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8519 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418520 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278521
[email protected]1c773ea12009-04-28 19:58:428522 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238523 MockWrite(
8524 "PUT / HTTP/1.1\r\n"
8525 "Host: www.example.org\r\n"
8526 "Connection: keep-alive\r\n"
8527 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428528 };
8529
8530 // Lastly, the server responds with the actual content.
8531 MockRead data_reads[] = {
8532 MockRead("HTTP/1.0 200 OK\r\n"),
8533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8534 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068535 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428536 };
8537
[email protected]31a2bfe2010-02-09 08:03:398538 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8539 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078540 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428541
[email protected]49639fa2011-12-20 23:22:418542 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428543
[email protected]49639fa2011-12-20 23:22:418544 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428545 EXPECT_EQ(ERR_IO_PENDING, rv);
8546
8547 rv = callback.WaitForResult();
8548 EXPECT_EQ(OK, rv);
8549}
8550
[email protected]23e482282013-06-14 16:08:028551TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428552 HttpRequestInfo request;
8553 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238554 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428555
danakj1fd259a02016-04-16 03:17:098556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8557 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418558 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278559
[email protected]1c773ea12009-04-28 19:58:428560 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138561 MockWrite("HEAD / HTTP/1.1\r\n"
8562 "Host: www.example.org\r\n"
8563 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428564 };
8565
8566 // Lastly, the server responds with the actual content.
8567 MockRead data_reads[] = {
8568 MockRead("HTTP/1.0 200 OK\r\n"),
8569 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8570 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068571 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428572 };
8573
[email protected]31a2bfe2010-02-09 08:03:398574 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8575 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078576 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428577
[email protected]49639fa2011-12-20 23:22:418578 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428579
[email protected]49639fa2011-12-20 23:22:418580 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428581 EXPECT_EQ(ERR_IO_PENDING, rv);
8582
8583 rv = callback.WaitForResult();
8584 EXPECT_EQ(OK, rv);
8585}
8586
[email protected]23e482282013-06-14 16:08:028587TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428588 HttpRequestInfo request;
8589 request.method = "GET";
bncce36dca22015-04-21 22:11:238590 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428591 request.load_flags = LOAD_BYPASS_CACHE;
8592
danakj1fd259a02016-04-16 03:17:098593 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8594 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418595 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278596
[email protected]1c773ea12009-04-28 19:58:428597 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238598 MockWrite(
8599 "GET / HTTP/1.1\r\n"
8600 "Host: www.example.org\r\n"
8601 "Connection: keep-alive\r\n"
8602 "Pragma: no-cache\r\n"
8603 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428604 };
8605
8606 // Lastly, the server responds with the actual content.
8607 MockRead data_reads[] = {
8608 MockRead("HTTP/1.0 200 OK\r\n"),
8609 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8610 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068611 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428612 };
8613
[email protected]31a2bfe2010-02-09 08:03:398614 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8615 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078616 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428617
[email protected]49639fa2011-12-20 23:22:418618 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428619
[email protected]49639fa2011-12-20 23:22:418620 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428621 EXPECT_EQ(ERR_IO_PENDING, rv);
8622
8623 rv = callback.WaitForResult();
8624 EXPECT_EQ(OK, rv);
8625}
8626
[email protected]23e482282013-06-14 16:08:028627TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:428628 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428629 HttpRequestInfo request;
8630 request.method = "GET";
bncce36dca22015-04-21 22:11:238631 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428632 request.load_flags = LOAD_VALIDATE_CACHE;
8633
danakj1fd259a02016-04-16 03:17:098634 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8635 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418636 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278637
[email protected]1c773ea12009-04-28 19:58:428638 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238639 MockWrite(
8640 "GET / HTTP/1.1\r\n"
8641 "Host: www.example.org\r\n"
8642 "Connection: keep-alive\r\n"
8643 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428644 };
8645
8646 // Lastly, the server responds with the actual content.
8647 MockRead data_reads[] = {
8648 MockRead("HTTP/1.0 200 OK\r\n"),
8649 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8650 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068651 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428652 };
8653
[email protected]31a2bfe2010-02-09 08:03:398654 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8655 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078656 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428657
[email protected]49639fa2011-12-20 23:22:418658 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428659
[email protected]49639fa2011-12-20 23:22:418660 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428661 EXPECT_EQ(ERR_IO_PENDING, rv);
8662
8663 rv = callback.WaitForResult();
8664 EXPECT_EQ(OK, rv);
8665}
8666
[email protected]23e482282013-06-14 16:08:028667TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428668 HttpRequestInfo request;
8669 request.method = "GET";
bncce36dca22015-04-21 22:11:238670 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438671 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428672
danakj1fd259a02016-04-16 03:17:098673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8674 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418675 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278676
[email protected]1c773ea12009-04-28 19:58:428677 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238678 MockWrite(
8679 "GET / HTTP/1.1\r\n"
8680 "Host: www.example.org\r\n"
8681 "Connection: keep-alive\r\n"
8682 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428683 };
8684
8685 // Lastly, the server responds with the actual content.
8686 MockRead data_reads[] = {
8687 MockRead("HTTP/1.0 200 OK\r\n"),
8688 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8689 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068690 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428691 };
8692
[email protected]31a2bfe2010-02-09 08:03:398693 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8694 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078695 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428696
[email protected]49639fa2011-12-20 23:22:418697 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428698
[email protected]49639fa2011-12-20 23:22:418699 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428700 EXPECT_EQ(ERR_IO_PENDING, rv);
8701
8702 rv = callback.WaitForResult();
8703 EXPECT_EQ(OK, rv);
8704}
8705
[email protected]23e482282013-06-14 16:08:028706TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478707 HttpRequestInfo request;
8708 request.method = "GET";
bncce36dca22015-04-21 22:11:238709 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438710 request.extra_headers.SetHeader("referer", "www.foo.com");
8711 request.extra_headers.SetHeader("hEllo", "Kitty");
8712 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478713
danakj1fd259a02016-04-16 03:17:098714 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8715 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418716 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278717
[email protected]270c6412010-03-29 22:02:478718 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238719 MockWrite(
8720 "GET / HTTP/1.1\r\n"
8721 "Host: www.example.org\r\n"
8722 "Connection: keep-alive\r\n"
8723 "referer: www.foo.com\r\n"
8724 "hEllo: Kitty\r\n"
8725 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478726 };
8727
8728 // Lastly, the server responds with the actual content.
8729 MockRead data_reads[] = {
8730 MockRead("HTTP/1.0 200 OK\r\n"),
8731 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8732 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068733 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478734 };
8735
8736 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8737 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078738 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478739
[email protected]49639fa2011-12-20 23:22:418740 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478741
[email protected]49639fa2011-12-20 23:22:418742 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:478743 EXPECT_EQ(ERR_IO_PENDING, rv);
8744
8745 rv = callback.WaitForResult();
8746 EXPECT_EQ(OK, rv);
8747}
8748
[email protected]23e482282013-06-14 16:08:028749TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278750 HttpRequestInfo request;
8751 request.method = "GET";
bncce36dca22015-04-21 22:11:238752 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278753 request.load_flags = 0;
8754
rdsmith82957ad2015-09-16 19:42:038755 session_deps_.proxy_service =
8756 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518757 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078758 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028759
danakj1fd259a02016-04-16 03:17:098760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8761 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418762 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028763
[email protected]3cd17242009-06-23 02:59:028764 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8765 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8766
8767 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238768 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8769 MockWrite(
8770 "GET / HTTP/1.1\r\n"
8771 "Host: www.example.org\r\n"
8772 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028773
8774 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068775 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028776 MockRead("HTTP/1.0 200 OK\r\n"),
8777 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8778 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068779 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028780 };
8781
[email protected]31a2bfe2010-02-09 08:03:398782 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8783 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078784 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028785
[email protected]49639fa2011-12-20 23:22:418786 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028787
[email protected]49639fa2011-12-20 23:22:418788 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028789 EXPECT_EQ(ERR_IO_PENDING, rv);
8790
8791 rv = callback.WaitForResult();
8792 EXPECT_EQ(OK, rv);
8793
8794 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528795 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028796
[email protected]029c83b62013-01-24 05:28:208797 LoadTimingInfo load_timing_info;
8798 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8799 TestLoadTimingNotReusedWithPac(load_timing_info,
8800 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8801
[email protected]3cd17242009-06-23 02:59:028802 std::string response_text;
8803 rv = ReadTransaction(trans.get(), &response_text);
8804 EXPECT_EQ(OK, rv);
8805 EXPECT_EQ("Payload", response_text);
8806}
8807
[email protected]23e482282013-06-14 16:08:028808TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278809 HttpRequestInfo request;
8810 request.method = "GET";
bncce36dca22015-04-21 22:11:238811 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278812 request.load_flags = 0;
8813
rdsmith82957ad2015-09-16 19:42:038814 session_deps_.proxy_service =
8815 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518816 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078817 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028818
danakj1fd259a02016-04-16 03:17:098819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8820 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418821 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028822
[email protected]3cd17242009-06-23 02:59:028823 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8824 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8825
8826 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238827 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8828 arraysize(write_buffer)),
8829 MockWrite(
8830 "GET / HTTP/1.1\r\n"
8831 "Host: www.example.org\r\n"
8832 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028833
8834 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018835 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8836 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358837 MockRead("HTTP/1.0 200 OK\r\n"),
8838 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8839 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068840 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358841 };
8842
[email protected]31a2bfe2010-02-09 08:03:398843 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8844 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078845 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358846
[email protected]8ddf8322012-02-23 18:08:068847 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078848 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358849
[email protected]49639fa2011-12-20 23:22:418850 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358851
[email protected]49639fa2011-12-20 23:22:418852 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358853 EXPECT_EQ(ERR_IO_PENDING, rv);
8854
8855 rv = callback.WaitForResult();
8856 EXPECT_EQ(OK, rv);
8857
[email protected]029c83b62013-01-24 05:28:208858 LoadTimingInfo load_timing_info;
8859 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8860 TestLoadTimingNotReusedWithPac(load_timing_info,
8861 CONNECT_TIMING_HAS_SSL_TIMES);
8862
[email protected]e0c27be2009-07-15 13:09:358863 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528864 ASSERT_TRUE(response);
[email protected]e0c27be2009-07-15 13:09:358865
8866 std::string response_text;
8867 rv = ReadTransaction(trans.get(), &response_text);
8868 EXPECT_EQ(OK, rv);
8869 EXPECT_EQ("Payload", response_text);
8870}
8871
[email protected]23e482282013-06-14 16:08:028872TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:208873 HttpRequestInfo request;
8874 request.method = "GET";
bncce36dca22015-04-21 22:11:238875 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:208876 request.load_flags = 0;
8877
rdsmith82957ad2015-09-16 19:42:038878 session_deps_.proxy_service =
8879 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518880 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078881 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:208882
danakj1fd259a02016-04-16 03:17:098883 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8884 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418885 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:208886
8887 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8888 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8889
8890 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238891 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8892 MockWrite(
8893 "GET / HTTP/1.1\r\n"
8894 "Host: www.example.org\r\n"
8895 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:208896
8897 MockRead data_reads[] = {
8898 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
8899 MockRead("HTTP/1.0 200 OK\r\n"),
8900 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8901 MockRead("Payload"),
8902 MockRead(SYNCHRONOUS, OK)
8903 };
8904
8905 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8906 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078907 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:208908
8909 TestCompletionCallback callback;
8910
8911 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8912 EXPECT_EQ(ERR_IO_PENDING, rv);
8913
8914 rv = callback.WaitForResult();
8915 EXPECT_EQ(OK, rv);
8916
8917 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528918 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:208919
8920 LoadTimingInfo load_timing_info;
8921 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8922 TestLoadTimingNotReused(load_timing_info,
8923 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8924
8925 std::string response_text;
8926 rv = ReadTransaction(trans.get(), &response_text);
8927 EXPECT_EQ(OK, rv);
8928 EXPECT_EQ("Payload", response_text);
8929}
8930
[email protected]23e482282013-06-14 16:08:028931TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278932 HttpRequestInfo request;
8933 request.method = "GET";
bncce36dca22015-04-21 22:11:238934 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278935 request.load_flags = 0;
8936
rdsmith82957ad2015-09-16 19:42:038937 session_deps_.proxy_service =
8938 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518939 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078940 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358941
danakj1fd259a02016-04-16 03:17:098942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8943 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418944 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358945
[email protected]e0c27be2009-07-15 13:09:358946 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8947 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378948 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238949 0x05, // Version
8950 0x01, // Command (CONNECT)
8951 0x00, // Reserved.
8952 0x03, // Address type (DOMAINNAME).
8953 0x0F, // Length of domain (15)
8954 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8955 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:378956 };
[email protected]e0c27be2009-07-15 13:09:358957 const char kSOCKS5OkResponse[] =
8958 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
8959
8960 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238961 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8962 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
8963 MockWrite(
8964 "GET / HTTP/1.1\r\n"
8965 "Host: www.example.org\r\n"
8966 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358967
8968 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018969 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8970 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:358971 MockRead("HTTP/1.0 200 OK\r\n"),
8972 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8973 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068974 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358975 };
8976
[email protected]31a2bfe2010-02-09 08:03:398977 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8978 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078979 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358980
[email protected]49639fa2011-12-20 23:22:418981 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358982
[email protected]49639fa2011-12-20 23:22:418983 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358984 EXPECT_EQ(ERR_IO_PENDING, rv);
8985
8986 rv = callback.WaitForResult();
8987 EXPECT_EQ(OK, rv);
8988
8989 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528990 ASSERT_TRUE(response);
[email protected]e0c27be2009-07-15 13:09:358991
[email protected]029c83b62013-01-24 05:28:208992 LoadTimingInfo load_timing_info;
8993 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8994 TestLoadTimingNotReusedWithPac(load_timing_info,
8995 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8996
[email protected]e0c27be2009-07-15 13:09:358997 std::string response_text;
8998 rv = ReadTransaction(trans.get(), &response_text);
8999 EXPECT_EQ(OK, rv);
9000 EXPECT_EQ("Payload", response_text);
9001}
9002
[email protected]23e482282013-06-14 16:08:029003TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279004 HttpRequestInfo request;
9005 request.method = "GET";
bncce36dca22015-04-21 22:11:239006 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279007 request.load_flags = 0;
9008
rdsmith82957ad2015-09-16 19:42:039009 session_deps_.proxy_service =
9010 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519011 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079012 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359013
danakj1fd259a02016-04-16 03:17:099014 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9015 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419016 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:359017
[email protected]e0c27be2009-07-15 13:09:359018 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9019 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379020 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239021 0x05, // Version
9022 0x01, // Command (CONNECT)
9023 0x00, // Reserved.
9024 0x03, // Address type (DOMAINNAME).
9025 0x0F, // Length of domain (15)
9026 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9027 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379028 };
9029
[email protected]e0c27be2009-07-15 13:09:359030 const char kSOCKS5OkResponse[] =
9031 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9032
9033 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239034 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9035 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9036 arraysize(kSOCKS5OkRequest)),
9037 MockWrite(
9038 "GET / HTTP/1.1\r\n"
9039 "Host: www.example.org\r\n"
9040 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359041
9042 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019043 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9044 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029045 MockRead("HTTP/1.0 200 OK\r\n"),
9046 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9047 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069048 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029049 };
9050
[email protected]31a2bfe2010-02-09 08:03:399051 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9052 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079053 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029054
[email protected]8ddf8322012-02-23 18:08:069055 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079056 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029057
[email protected]49639fa2011-12-20 23:22:419058 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029059
[email protected]49639fa2011-12-20 23:22:419060 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:029061 EXPECT_EQ(ERR_IO_PENDING, rv);
9062
9063 rv = callback.WaitForResult();
9064 EXPECT_EQ(OK, rv);
9065
9066 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529067 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029068
[email protected]029c83b62013-01-24 05:28:209069 LoadTimingInfo load_timing_info;
9070 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9071 TestLoadTimingNotReusedWithPac(load_timing_info,
9072 CONNECT_TIMING_HAS_SSL_TIMES);
9073
[email protected]3cd17242009-06-23 02:59:029074 std::string response_text;
9075 rv = ReadTransaction(trans.get(), &response_text);
9076 EXPECT_EQ(OK, rv);
9077 EXPECT_EQ("Payload", response_text);
9078}
9079
[email protected]448d4ca52012-03-04 04:12:239080namespace {
9081
[email protected]04e5be32009-06-26 20:00:319082// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069083
9084struct GroupNameTest {
9085 std::string proxy_server;
9086 std::string url;
9087 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189088 bool ssl;
[email protected]2d731a32010-04-29 01:04:069089};
9090
danakj1fd259a02016-04-16 03:17:099091std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:439092 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:079093 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099094 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069095
[email protected]30d4c022013-07-18 22:58:169096 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539097 session->http_server_properties();
bnccacc0992015-03-20 20:22:229098 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:259099 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:129100 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229101 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:469102 url::SchemeHostPort("http", "host.with.alternate", 80),
9103 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069104
9105 return session;
9106}
9107
mmenkee65e7af2015-10-13 17:16:429108int GroupNameTransactionHelper(const std::string& url,
9109 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069110 HttpRequestInfo request;
9111 request.method = "GET";
9112 request.url = GURL(url);
9113 request.load_flags = 0;
9114
danakj1fd259a02016-04-16 03:17:099115 std::unique_ptr<HttpTransaction> trans(
mmenkee65e7af2015-10-13 17:16:429116 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:279117
[email protected]49639fa2011-12-20 23:22:419118 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069119
9120 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:419121 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:069122}
9123
[email protected]448d4ca52012-03-04 04:12:239124} // namespace
9125
[email protected]23e482282013-06-14 16:08:029126TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069127 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239128 {
9129 "", // unused
9130 "http://www.example.org/direct",
9131 "www.example.org:80",
9132 false,
9133 },
9134 {
9135 "", // unused
9136 "http://[2001:1418:13:1::25]/direct",
9137 "[2001:1418:13:1::25]:80",
9138 false,
9139 },
[email protected]04e5be32009-06-26 20:00:319140
bncce36dca22015-04-21 22:11:239141 // SSL Tests
9142 {
9143 "", // unused
9144 "https://www.example.org/direct_ssl",
9145 "ssl/www.example.org:443",
9146 true,
9147 },
9148 {
9149 "", // unused
9150 "https://[2001:1418:13:1::25]/direct",
9151 "ssl/[2001:1418:13:1::25]:443",
9152 true,
9153 },
9154 {
9155 "", // unused
9156 "http://host.with.alternate/direct",
9157 "ssl/host.with.alternate:443",
9158 true,
9159 },
[email protected]2d731a32010-04-29 01:04:069160 };
[email protected]2ff8b312010-04-26 22:20:549161
bncf33fb31b2016-01-29 15:22:269162 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d731a32010-04-29 01:04:069163
viettrungluue4a8b882014-10-16 06:17:389164 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039165 session_deps_.proxy_service =
9166 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099167 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:389168 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:069169
mmenkee65e7af2015-10-13 17:16:429170 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289171 CaptureGroupNameTransportSocketPool* transport_conn_pool =
9172 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139173 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349174 new CaptureGroupNameSSLSocketPool(NULL, NULL);
danakj1fd259a02016-04-16 03:17:099175 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449176 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029177 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9178 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489179 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069180
9181 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429182 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189183 if (tests[i].ssl)
9184 EXPECT_EQ(tests[i].expected_group_name,
9185 ssl_conn_pool->last_group_name_received());
9186 else
9187 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289188 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069189 }
[email protected]2d731a32010-04-29 01:04:069190}
9191
[email protected]23e482282013-06-14 16:08:029192TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069193 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239194 {
9195 "http_proxy",
9196 "http://www.example.org/http_proxy_normal",
9197 "www.example.org:80",
9198 false,
9199 },
[email protected]2d731a32010-04-29 01:04:069200
bncce36dca22015-04-21 22:11:239201 // SSL Tests
9202 {
9203 "http_proxy",
9204 "https://www.example.org/http_connect_ssl",
9205 "ssl/www.example.org:443",
9206 true,
9207 },
[email protected]af3490e2010-10-16 21:02:299208
bncce36dca22015-04-21 22:11:239209 {
9210 "http_proxy",
9211 "http://host.with.alternate/direct",
9212 "ssl/host.with.alternate:443",
9213 true,
9214 },
[email protected]45499252013-01-23 17:12:569215
bncce36dca22015-04-21 22:11:239216 {
9217 "http_proxy",
9218 "ftp://ftp.google.com/http_proxy_normal",
9219 "ftp/ftp.google.com:21",
9220 false,
9221 },
[email protected]2d731a32010-04-29 01:04:069222 };
9223
bncf33fb31b2016-01-29 15:22:269224 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d731a32010-04-29 01:04:069225
viettrungluue4a8b882014-10-16 06:17:389226 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039227 session_deps_.proxy_service =
9228 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099229 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:389230 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:069231
mmenkee65e7af2015-10-13 17:16:429232 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069233
[email protected]e60e47a2010-07-14 03:37:189234 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139235 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349236 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139237 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349238 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029239
danakj1fd259a02016-04-16 03:17:099240 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449241 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029242 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
9243 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489244 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069245
9246 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429247 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189248 if (tests[i].ssl)
9249 EXPECT_EQ(tests[i].expected_group_name,
9250 ssl_conn_pool->last_group_name_received());
9251 else
9252 EXPECT_EQ(tests[i].expected_group_name,
9253 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069254 }
[email protected]2d731a32010-04-29 01:04:069255}
9256
[email protected]23e482282013-06-14 16:08:029257TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069258 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239259 {
9260 "socks4://socks_proxy:1080",
9261 "http://www.example.org/socks4_direct",
9262 "socks4/www.example.org:80",
9263 false,
9264 },
9265 {
9266 "socks5://socks_proxy:1080",
9267 "http://www.example.org/socks5_direct",
9268 "socks5/www.example.org:80",
9269 false,
9270 },
[email protected]2d731a32010-04-29 01:04:069271
bncce36dca22015-04-21 22:11:239272 // SSL Tests
9273 {
9274 "socks4://socks_proxy:1080",
9275 "https://www.example.org/socks4_ssl",
9276 "socks4/ssl/www.example.org:443",
9277 true,
9278 },
9279 {
9280 "socks5://socks_proxy:1080",
9281 "https://www.example.org/socks5_ssl",
9282 "socks5/ssl/www.example.org:443",
9283 true,
9284 },
[email protected]af3490e2010-10-16 21:02:299285
bncce36dca22015-04-21 22:11:239286 {
9287 "socks4://socks_proxy:1080",
9288 "http://host.with.alternate/direct",
9289 "socks4/ssl/host.with.alternate:443",
9290 true,
9291 },
[email protected]04e5be32009-06-26 20:00:319292 };
9293
bncf33fb31b2016-01-29 15:22:269294 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2ff8b312010-04-26 22:20:549295
viettrungluue4a8b882014-10-16 06:17:389296 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039297 session_deps_.proxy_service =
9298 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099299 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:389300 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:029301
mmenkee65e7af2015-10-13 17:16:429302 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319303
[email protected]e60e47a2010-07-14 03:37:189304 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139305 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349306 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139307 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349308 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029309
danakj1fd259a02016-04-16 03:17:099310 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449311 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029312 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
9313 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489314 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319315
danakj1fd259a02016-04-16 03:17:099316 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509317 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:319318
[email protected]2d731a32010-04-29 01:04:069319 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429320 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189321 if (tests[i].ssl)
9322 EXPECT_EQ(tests[i].expected_group_name,
9323 ssl_conn_pool->last_group_name_received());
9324 else
9325 EXPECT_EQ(tests[i].expected_group_name,
9326 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319327 }
9328}
9329
[email protected]23e482282013-06-14 16:08:029330TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279331 HttpRequestInfo request;
9332 request.method = "GET";
bncce36dca22015-04-21 22:11:239333 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279334
rdsmith82957ad2015-09-16 19:42:039335 session_deps_.proxy_service =
9336 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329337
[email protected]69719062010-01-05 20:09:219338 // This simulates failure resolving all hostnames; that means we will fail
9339 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079340 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329341
danakj1fd259a02016-04-16 03:17:099342 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9343 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419344 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:259345
[email protected]49639fa2011-12-20 23:22:419346 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259347
[email protected]49639fa2011-12-20 23:22:419348 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:259349 EXPECT_EQ(ERR_IO_PENDING, rv);
9350
[email protected]9172a982009-06-06 00:30:259351 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:019352 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:259353}
9354
[email protected]685af592010-05-11 19:31:249355// Base test to make sure that when the load flags for a request specify to
9356// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029357void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079358 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279359 // Issue a request, asking to bypass the cache(s).
9360 HttpRequestInfo request;
9361 request.method = "GET";
9362 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:239363 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279364
[email protected]a2c2fb92009-07-18 07:31:049365 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:079366 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:329367
danakj1fd259a02016-04-16 03:17:099368 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9369 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419370 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:289371
bncce36dca22015-04-21 22:11:239372 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289373 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299374 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:079375 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239376 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
9377 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:479378 EXPECT_EQ(ERR_IO_PENDING, rv);
9379 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289380 EXPECT_EQ(OK, rv);
9381
9382 // Verify that it was added to host cache, by doing a subsequent async lookup
9383 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:079384 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239385 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
9386 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:329387 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:289388
bncce36dca22015-04-21 22:11:239389 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289390 // we can tell if the next lookup hit the cache, or the "network".
9391 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239392 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289393
9394 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9395 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069396 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399397 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079398 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289399
[email protected]3b9cca42009-06-16 01:08:289400 // Run the request.
[email protected]49639fa2011-12-20 23:22:419401 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:289402 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419403 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289404
9405 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239406 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289407 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
9408}
9409
[email protected]685af592010-05-11 19:31:249410// There are multiple load flags that should trigger the host cache bypass.
9411// Test each in isolation:
[email protected]23e482282013-06-14 16:08:029412TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249413 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9414}
9415
[email protected]23e482282013-06-14 16:08:029416TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249417 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9418}
9419
[email protected]23e482282013-06-14 16:08:029420TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249421 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9422}
9423
[email protected]0877e3d2009-10-17 22:29:579424// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:029425TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579426 HttpRequestInfo request;
9427 request.method = "GET";
9428 request.url = GURL("http://www.foo.com/");
9429 request.load_flags = 0;
9430
9431 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069432 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579433 };
[email protected]31a2bfe2010-02-09 08:03:399434 StaticSocketDataProvider data(NULL, 0,
9435 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079436 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099437 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579438
[email protected]49639fa2011-12-20 23:22:419439 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579440
danakj1fd259a02016-04-16 03:17:099441 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419442 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579443
[email protected]49639fa2011-12-20 23:22:419444 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579445 EXPECT_EQ(ERR_IO_PENDING, rv);
9446
9447 rv = callback.WaitForResult();
9448 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:599449
9450 IPEndPoint endpoint;
9451 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
9452 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579453}
9454
zmo9528c9f42015-08-04 22:12:089455// Check that a connection closed after the start of the headers finishes ok.
9456TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579457 HttpRequestInfo request;
9458 request.method = "GET";
9459 request.url = GURL("http://www.foo.com/");
9460 request.load_flags = 0;
9461
9462 MockRead data_reads[] = {
9463 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069464 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579465 };
9466
[email protected]31a2bfe2010-02-09 08:03:399467 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079468 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099469 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579470
[email protected]49639fa2011-12-20 23:22:419471 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579472
danakj1fd259a02016-04-16 03:17:099473 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419474 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579475
[email protected]49639fa2011-12-20 23:22:419476 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579477 EXPECT_EQ(ERR_IO_PENDING, rv);
9478
9479 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:089480 EXPECT_EQ(OK, rv);
9481
9482 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529483 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089484
wezca1070932016-05-26 20:30:529485 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089486 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9487
9488 std::string response_data;
9489 rv = ReadTransaction(trans.get(), &response_data);
9490 EXPECT_EQ(OK, rv);
9491 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599492
9493 IPEndPoint endpoint;
9494 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
9495 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579496}
9497
9498// Make sure that a dropped connection while draining the body for auth
9499// restart does the right thing.
[email protected]23e482282013-06-14 16:08:029500TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579501 HttpRequestInfo request;
9502 request.method = "GET";
bncce36dca22015-04-21 22:11:239503 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579504 request.load_flags = 0;
9505
9506 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239507 MockWrite(
9508 "GET / HTTP/1.1\r\n"
9509 "Host: www.example.org\r\n"
9510 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579511 };
9512
9513 MockRead data_reads1[] = {
9514 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9515 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9516 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9517 MockRead("Content-Length: 14\r\n\r\n"),
9518 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069519 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579520 };
9521
[email protected]31a2bfe2010-02-09 08:03:399522 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9523 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079524 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579525
9526 // After calling trans->RestartWithAuth(), this is the request we should
9527 // be issuing -- the final header line contains the credentials.
9528 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239529 MockWrite(
9530 "GET / HTTP/1.1\r\n"
9531 "Host: www.example.org\r\n"
9532 "Connection: keep-alive\r\n"
9533 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579534 };
9535
9536 // Lastly, the server responds with the actual content.
9537 MockRead data_reads2[] = {
9538 MockRead("HTTP/1.1 200 OK\r\n"),
9539 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9540 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069541 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579542 };
9543
[email protected]31a2bfe2010-02-09 08:03:399544 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9545 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079546 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099547 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579548
[email protected]49639fa2011-12-20 23:22:419549 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579550
danakj1fd259a02016-04-16 03:17:099551 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509552 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509553
[email protected]49639fa2011-12-20 23:22:419554 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579555 EXPECT_EQ(ERR_IO_PENDING, rv);
9556
9557 rv = callback1.WaitForResult();
9558 EXPECT_EQ(OK, rv);
9559
9560 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529561 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049562 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579563
[email protected]49639fa2011-12-20 23:22:419564 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579565
[email protected]49639fa2011-12-20 23:22:419566 rv = trans->RestartWithAuth(
9567 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:579568 EXPECT_EQ(ERR_IO_PENDING, rv);
9569
9570 rv = callback2.WaitForResult();
9571 EXPECT_EQ(OK, rv);
9572
9573 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529574 ASSERT_TRUE(response);
9575 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579576 EXPECT_EQ(100, response->headers->GetContentLength());
9577}
9578
9579// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:029580TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039581 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579582
9583 HttpRequestInfo request;
9584 request.method = "GET";
bncce36dca22015-04-21 22:11:239585 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579586 request.load_flags = 0;
9587
9588 MockRead proxy_reads[] = {
9589 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069590 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579591 };
9592
[email protected]31a2bfe2010-02-09 08:03:399593 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069594 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579595
[email protected]bb88e1d32013-05-03 23:11:079596 session_deps_.socket_factory->AddSocketDataProvider(&data);
9597 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579598
[email protected]49639fa2011-12-20 23:22:419599 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579600
[email protected]bb88e1d32013-05-03 23:11:079601 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579602
danakj1fd259a02016-04-16 03:17:099603 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9604 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579606
[email protected]49639fa2011-12-20 23:22:419607 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579608 EXPECT_EQ(ERR_IO_PENDING, rv);
9609
9610 rv = callback.WaitForResult();
9611 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
9612}
9613
[email protected]23e482282013-06-14 16:08:029614TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469615 HttpRequestInfo request;
9616 request.method = "GET";
bncce36dca22015-04-21 22:11:239617 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469618 request.load_flags = 0;
9619
danakj1fd259a02016-04-16 03:17:099620 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9621 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419622 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:279623
[email protected]e22e1362009-11-23 21:31:129624 MockRead data_reads[] = {
9625 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069626 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129627 };
[email protected]9492e4a2010-02-24 00:58:469628
9629 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079630 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469631
[email protected]49639fa2011-12-20 23:22:419632 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469633
[email protected]49639fa2011-12-20 23:22:419634 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:469635 EXPECT_EQ(ERR_IO_PENDING, rv);
9636
9637 EXPECT_EQ(OK, callback.WaitForResult());
9638
9639 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529640 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469641
wezca1070932016-05-26 20:30:529642 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469643 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9644
9645 std::string response_data;
9646 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:239647 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:129648}
9649
[email protected]23e482282013-06-14 16:08:029650TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159651 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529652 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149653 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219654 UploadFileElementReader::ScopedOverridingContentLengthForTests
9655 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339656
danakj1fd259a02016-04-16 03:17:099657 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9658 element_readers.push_back(base::WrapUnique(new UploadFileElementReader(
avibf0746c2015-12-09 19:53:149659 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
9660 std::numeric_limits<uint64_t>::max(), base::Time())));
olli.raula6df48b2a2015-11-26 07:40:229661 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279662
9663 HttpRequestInfo request;
9664 request.method = "POST";
bncce36dca22015-04-21 22:11:239665 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279666 request.upload_data_stream = &upload_data_stream;
9667 request.load_flags = 0;
9668
danakj1fd259a02016-04-16 03:17:099669 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9670 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419671 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:339672
9673 MockRead data_reads[] = {
9674 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9675 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069676 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339677 };
[email protected]31a2bfe2010-02-09 08:03:399678 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079679 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339680
[email protected]49639fa2011-12-20 23:22:419681 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339682
[email protected]49639fa2011-12-20 23:22:419683 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:339684 EXPECT_EQ(ERR_IO_PENDING, rv);
9685
9686 rv = callback.WaitForResult();
9687 EXPECT_EQ(OK, rv);
9688
9689 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529690 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339691
wezca1070932016-05-26 20:30:529692 EXPECT_TRUE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339693 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9694
9695 std::string response_data;
9696 rv = ReadTransaction(trans.get(), &response_data);
9697 EXPECT_EQ(OK, rv);
9698 EXPECT_EQ("hello world", response_data);
9699
[email protected]dd3aa792013-07-16 19:10:239700 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339701}
9702
[email protected]23e482282013-06-14 16:08:029703TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159704 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529705 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369706 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309707 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369708 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119709 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369710
danakj1fd259a02016-04-16 03:17:099711 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9712 element_readers.push_back(base::WrapUnique(new UploadFileElementReader(
avibf0746c2015-12-09 19:53:149713 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
9714 std::numeric_limits<uint64_t>::max(), base::Time())));
olli.raula6df48b2a2015-11-26 07:40:229715 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279716
9717 HttpRequestInfo request;
9718 request.method = "POST";
bncce36dca22015-04-21 22:11:239719 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279720 request.upload_data_stream = &upload_data_stream;
9721 request.load_flags = 0;
9722
[email protected]999dd8c2013-11-12 06:45:549723 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099724 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9725 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419726 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:369727
[email protected]999dd8c2013-11-12 06:45:549728 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079729 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369730
[email protected]49639fa2011-12-20 23:22:419731 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369732
[email protected]49639fa2011-12-20 23:22:419733 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:369734 EXPECT_EQ(ERR_IO_PENDING, rv);
9735
9736 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:549737 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:369738
[email protected]dd3aa792013-07-16 19:10:239739 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369740}
9741
[email protected]02cad5d2013-10-02 08:14:039742TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
9743 class FakeUploadElementReader : public UploadElementReader {
9744 public:
9745 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209746 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039747
9748 const CompletionCallback& callback() const { return callback_; }
9749
9750 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209751 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039752 callback_ = callback;
9753 return ERR_IO_PENDING;
9754 }
avibf0746c2015-12-09 19:53:149755 uint64_t GetContentLength() const override { return 0; }
9756 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209757 int Read(IOBuffer* buf,
9758 int buf_length,
9759 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039760 return ERR_FAILED;
9761 }
9762
9763 private:
9764 CompletionCallback callback_;
9765 };
9766
9767 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099768 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9769 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229770 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039771
9772 HttpRequestInfo request;
9773 request.method = "POST";
bncce36dca22015-04-21 22:11:239774 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039775 request.upload_data_stream = &upload_data_stream;
9776 request.load_flags = 0;
9777
danakj1fd259a02016-04-16 03:17:099778 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9779 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419780 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039781
9782 StaticSocketDataProvider data;
9783 session_deps_.socket_factory->AddSocketDataProvider(&data);
9784
9785 TestCompletionCallback callback;
9786 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9787 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:559788 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039789
9790 // Transaction is pending on request body initialization.
9791 ASSERT_FALSE(fake_reader->callback().is_null());
9792
9793 // Return Init()'s result after the transaction gets destroyed.
9794 trans.reset();
9795 fake_reader->callback().Run(OK); // Should not crash.
9796}
9797
[email protected]aeefc9e82010-02-19 16:18:279798// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:029799TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279800 HttpRequestInfo request;
9801 request.method = "GET";
bncce36dca22015-04-21 22:11:239802 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279803 request.load_flags = 0;
9804
9805 // First transaction will request a resource and receive a Basic challenge
9806 // with realm="first_realm".
9807 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239808 MockWrite(
9809 "GET / HTTP/1.1\r\n"
9810 "Host: www.example.org\r\n"
9811 "Connection: keep-alive\r\n"
9812 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279813 };
9814 MockRead data_reads1[] = {
9815 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9816 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9817 "\r\n"),
9818 };
9819
9820 // After calling trans->RestartWithAuth(), provide an Authentication header
9821 // for first_realm. The server will reject and provide a challenge with
9822 // second_realm.
9823 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239824 MockWrite(
9825 "GET / HTTP/1.1\r\n"
9826 "Host: www.example.org\r\n"
9827 "Connection: keep-alive\r\n"
9828 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9829 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279830 };
9831 MockRead data_reads2[] = {
9832 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9833 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9834 "\r\n"),
9835 };
9836
9837 // This again fails, and goes back to first_realm. Make sure that the
9838 // entry is removed from cache.
9839 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239840 MockWrite(
9841 "GET / HTTP/1.1\r\n"
9842 "Host: www.example.org\r\n"
9843 "Connection: keep-alive\r\n"
9844 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9845 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279846 };
9847 MockRead data_reads3[] = {
9848 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9849 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9850 "\r\n"),
9851 };
9852
9853 // Try one last time (with the correct password) and get the resource.
9854 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239855 MockWrite(
9856 "GET / HTTP/1.1\r\n"
9857 "Host: www.example.org\r\n"
9858 "Connection: keep-alive\r\n"
9859 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9860 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279861 };
9862 MockRead data_reads4[] = {
9863 MockRead("HTTP/1.1 200 OK\r\n"
9864 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509865 "Content-Length: 5\r\n"
9866 "\r\n"
9867 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279868 };
9869
9870 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9871 data_writes1, arraysize(data_writes1));
9872 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9873 data_writes2, arraysize(data_writes2));
9874 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9875 data_writes3, arraysize(data_writes3));
9876 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9877 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079878 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9879 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9880 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9881 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279882
[email protected]49639fa2011-12-20 23:22:419883 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279884
danakj1fd259a02016-04-16 03:17:099885 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9886 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419887 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509888
[email protected]aeefc9e82010-02-19 16:18:279889 // Issue the first request with Authorize headers. There should be a
9890 // password prompt for first_realm waiting to be filled in after the
9891 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419892 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:279893 EXPECT_EQ(ERR_IO_PENDING, rv);
9894 rv = callback1.WaitForResult();
9895 EXPECT_EQ(OK, rv);
9896 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529897 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049898 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529899 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049900 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439901 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049902 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199903 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279904
9905 // Issue the second request with an incorrect password. There should be a
9906 // password prompt for second_realm waiting to be filled in after the
9907 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419908 TestCompletionCallback callback2;
9909 rv = trans->RestartWithAuth(
9910 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:279911 EXPECT_EQ(ERR_IO_PENDING, rv);
9912 rv = callback2.WaitForResult();
9913 EXPECT_EQ(OK, rv);
9914 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529915 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049916 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529917 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049918 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439919 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049920 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199921 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279922
9923 // Issue the third request with another incorrect password. There should be
9924 // a password prompt for first_realm waiting to be filled in. If the password
9925 // prompt is not present, it indicates that the HttpAuthCacheEntry for
9926 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:419927 TestCompletionCallback callback3;
9928 rv = trans->RestartWithAuth(
9929 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:279930 EXPECT_EQ(ERR_IO_PENDING, rv);
9931 rv = callback3.WaitForResult();
9932 EXPECT_EQ(OK, rv);
9933 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529934 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049935 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529936 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049937 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439938 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049939 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199940 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279941
9942 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:419943 TestCompletionCallback callback4;
9944 rv = trans->RestartWithAuth(
9945 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:279946 EXPECT_EQ(ERR_IO_PENDING, rv);
9947 rv = callback4.WaitForResult();
9948 EXPECT_EQ(OK, rv);
9949 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529950 ASSERT_TRUE(response);
9951 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:279952}
9953
bncc958faa2015-07-31 18:14:529954TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:269955 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:529956
9957 std::string alternative_service_http_header =
9958 GetAlternativeServiceHttpHeader();
9959
9960 MockRead data_reads[] = {
9961 MockRead("HTTP/1.1 200 OK\r\n"),
9962 MockRead(alternative_service_http_header.c_str()),
9963 MockRead("\r\n"),
9964 MockRead("hello world"),
9965 MockRead(SYNCHRONOUS, OK),
9966 };
9967
9968 HttpRequestInfo request;
9969 request.method = "GET";
9970 request.url = GURL("http://www.example.org/");
9971 request.load_flags = 0;
9972
9973 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9974
9975 session_deps_.socket_factory->AddSocketDataProvider(&data);
9976
9977 TestCompletionCallback callback;
9978
danakj1fd259a02016-04-16 03:17:099979 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9980 std::unique_ptr<HttpTransaction> trans(
bncc958faa2015-07-31 18:14:529981 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9982
9983 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9984 EXPECT_EQ(ERR_IO_PENDING, rv);
9985
zhongyi3d4a55e72016-04-22 20:36:469986 url::SchemeHostPort test_server("http", "www.example.org", 80);
bncc958faa2015-07-31 18:14:529987 HttpServerProperties& http_server_properties =
9988 *session->http_server_properties();
9989 AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469990 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529991 EXPECT_TRUE(alternative_service_vector.empty());
9992
9993 EXPECT_EQ(OK, callback.WaitForResult());
9994
9995 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529996 ASSERT_TRUE(response);
9997 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:529998 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9999 EXPECT_FALSE(response->was_fetched_via_spdy);
10000 EXPECT_FALSE(response->was_npn_negotiated);
10001
10002 std::string response_data;
10003 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10004 EXPECT_EQ("hello world", response_data);
10005
10006 alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610007 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210008 ASSERT_EQ(1u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:3810009 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:5210010 alternative_service_vector[0].protocol);
bnc8bef8da22016-05-30 01:28:2510011 EXPECT_EQ("www.example.org", alternative_service_vector[0].host);
bncc958faa2015-07-31 18:14:5210012 EXPECT_EQ(443, alternative_service_vector[0].port);
10013}
10014
bnce3dd56f2016-06-01 10:37:1110015// Regression test for https://crbug.com/615497.
10016TEST_P(HttpNetworkTransactionTest,
10017 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
10018 session_deps_.enable_alternative_service_for_insecure_origins = false;
10019
10020 std::string alternative_service_http_header =
10021 GetAlternativeServiceHttpHeader();
10022
10023 MockRead data_reads[] = {
10024 MockRead("HTTP/1.1 200 OK\r\n"),
10025 MockRead(alternative_service_http_header.c_str()),
10026 MockRead("\r\n"),
10027 MockRead("hello world"),
10028 MockRead(SYNCHRONOUS, OK),
10029 };
10030
10031 HttpRequestInfo request;
10032 request.method = "GET";
10033 request.url = GURL("http://www.example.org/");
10034 request.load_flags = 0;
10035
10036 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10037 session_deps_.socket_factory->AddSocketDataProvider(&data);
10038
10039 TestCompletionCallback callback;
10040
10041 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10042 std::unique_ptr<HttpTransaction> trans(
10043 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10044
10045 url::SchemeHostPort test_server(request.url);
10046 HttpServerProperties& http_server_properties =
10047 *session->http_server_properties();
10048 AlternativeServiceVector alternative_service_vector =
10049 http_server_properties.GetAlternativeServices(test_server);
10050 EXPECT_TRUE(alternative_service_vector.empty());
10051
10052 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10053 EXPECT_EQ(ERR_IO_PENDING, rv);
10054 EXPECT_EQ(OK, callback.WaitForResult());
10055
10056 const HttpResponseInfo* response = trans->GetResponseInfo();
10057 ASSERT_TRUE(response);
10058 ASSERT_TRUE(response->headers);
10059 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10060 EXPECT_FALSE(response->was_fetched_via_spdy);
10061 EXPECT_FALSE(response->was_npn_negotiated);
10062
10063 std::string response_data;
10064 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10065 EXPECT_EQ("hello world", response_data);
10066
10067 alternative_service_vector =
10068 http_server_properties.GetAlternativeServices(test_server);
10069 EXPECT_TRUE(alternative_service_vector.empty());
10070}
10071
bnc8bef8da22016-05-30 01:28:2510072// HTTP/2 Alternative Services should be disabled if alternative service
10073// hostname is different from that of origin.
10074// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
10075TEST_P(HttpNetworkTransactionTest,
10076 DisableHTTP2AlternativeServicesWithDifferentHost) {
10077 session_deps_.enable_alternative_service_with_different_host = true;
10078
10079 HttpRequestInfo request;
10080 request.method = "GET";
10081 request.url = GURL("http://www.example.org/");
10082 request.load_flags = 0;
10083
10084 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10085 StaticSocketDataProvider first_data;
10086 first_data.set_connect_data(mock_connect);
10087 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10088
10089 MockRead data_reads[] = {
10090 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10091 MockRead(ASYNC, OK),
10092 };
10093 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10094 0);
10095 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10096
10097 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10098
10099 base::WeakPtr<HttpServerProperties> http_server_properties =
10100 session->http_server_properties();
10101 AlternativeService alternative_service(
10102 AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
10103 444);
10104 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10105 http_server_properties->SetAlternativeService(
10106 url::SchemeHostPort(request.url), alternative_service, expiration);
10107
10108 std::unique_ptr<HttpTransaction> trans(
10109 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10110 TestCompletionCallback callback;
10111
10112 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10113 // Alternative service is not used, request fails.
10114 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
10115}
10116
bnce3dd56f2016-06-01 10:37:1110117// Regression test for https://crbug.com/615497:
10118// Alternative Services should be disabled for http origin.
10119TEST_P(HttpNetworkTransactionTest,
10120 DisableAlternativeServicesForInsecureOrigin) {
10121 session_deps_.enable_alternative_service_for_insecure_origins = false;
10122
10123 HttpRequestInfo request;
10124 request.method = "GET";
10125 request.url = GURL("http://www.example.org/");
10126 request.load_flags = 0;
10127
10128 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10129 StaticSocketDataProvider first_data;
10130 first_data.set_connect_data(mock_connect);
10131 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10132
10133 MockRead data_reads[] = {
10134 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10135 MockRead(ASYNC, OK),
10136 };
10137 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10138 0);
10139 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10140
10141 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10142
10143 base::WeakPtr<HttpServerProperties> http_server_properties =
10144 session->http_server_properties();
10145 AlternativeService alternative_service(
10146 AlternateProtocolFromNextProto(GetProtocol()), "", 444);
10147 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10148 http_server_properties->SetAlternativeService(
10149 url::SchemeHostPort(request.url), alternative_service, expiration);
10150
10151 std::unique_ptr<HttpTransaction> trans(
10152 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10153 TestCompletionCallback callback;
10154
10155 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10156 // Alternative service is not used, request fails.
10157 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
10158}
10159
bnc4f575852015-10-14 18:35:0810160TEST_P(HttpNetworkTransactionTest, ClearAlternativeServices) {
bncf33fb31b2016-01-29 15:22:2610161 session_deps_.enable_alternative_service_with_different_host = false;
bnc4f575852015-10-14 18:35:0810162
10163 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910164 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc4f575852015-10-14 18:35:0810165 HttpServerProperties& http_server_properties =
10166 *session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610167 url::SchemeHostPort test_server("http", "www.example.org", 80);
bnc4f575852015-10-14 18:35:0810168 AlternativeService alternative_service(QUIC, "", 80);
10169 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610170 http_server_properties.SetAlternativeService(test_server, alternative_service,
10171 expiration);
bnc4f575852015-10-14 18:35:0810172 AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610173 http_server_properties.GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810174 EXPECT_EQ(1u, alternative_service_vector.size());
10175
10176 // Send a clear header.
10177 MockRead data_reads[] = {
10178 MockRead("HTTP/1.1 200 OK\r\n"),
10179 MockRead("Alt-Svc: clear\r\n"),
10180 MockRead("\r\n"),
10181 MockRead("hello world"),
10182 MockRead(SYNCHRONOUS, OK),
10183 };
10184 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10185 session_deps_.socket_factory->AddSocketDataProvider(&data);
10186
10187 HttpRequestInfo request;
10188 request.method = "GET";
10189 request.url = GURL("http://www.example.org/");
10190 request.load_flags = 0;
10191
10192 TestCompletionCallback callback;
10193
danakj1fd259a02016-04-16 03:17:0910194 std::unique_ptr<HttpTransaction> trans(
bnc4f575852015-10-14 18:35:0810195 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10196
10197 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10198 EXPECT_EQ(OK, callback.GetResult(rv));
10199
10200 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210201 ASSERT_TRUE(response);
10202 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810203 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10204 EXPECT_FALSE(response->was_fetched_via_spdy);
10205 EXPECT_FALSE(response->was_npn_negotiated);
10206
10207 std::string response_data;
10208 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10209 EXPECT_EQ("hello world", response_data);
10210
10211 alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610212 http_server_properties.GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810213 EXPECT_TRUE(alternative_service_vector.empty());
10214}
10215
bncc958faa2015-07-31 18:14:5210216TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:2610217 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:5210218
10219 MockRead data_reads[] = {
10220 MockRead("HTTP/1.1 200 OK\r\n"),
10221 MockRead("Alt-Svc: "),
10222 MockRead(GetAlternateProtocolFromParam()),
bnc44858c82015-10-16 11:57:2110223 MockRead("=\"www.example.com:443\";p=\"1.0\","),
bnc3f0118e2016-02-02 15:42:2210224 MockRead(GetAlternateProtocolFromParam()),
10225 MockRead("=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210226 MockRead("hello world"),
10227 MockRead(SYNCHRONOUS, OK),
10228 };
10229
10230 HttpRequestInfo request;
10231 request.method = "GET";
10232 request.url = GURL("http://www.example.org/");
10233 request.load_flags = 0;
10234
10235 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10236
10237 session_deps_.socket_factory->AddSocketDataProvider(&data);
10238
10239 TestCompletionCallback callback;
10240
danakj1fd259a02016-04-16 03:17:0910241 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10242 std::unique_ptr<HttpTransaction> trans(
bncc958faa2015-07-31 18:14:5210243 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10244
10245 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10246 EXPECT_EQ(ERR_IO_PENDING, rv);
10247
zhongyi3d4a55e72016-04-22 20:36:4610248 url::SchemeHostPort test_server("http", "www.example.org", 80);
bncc958faa2015-07-31 18:14:5210249 HttpServerProperties& http_server_properties =
10250 *session->http_server_properties();
10251 AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610252 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210253 EXPECT_TRUE(alternative_service_vector.empty());
10254
10255 EXPECT_EQ(OK, callback.WaitForResult());
10256
10257 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210258 ASSERT_TRUE(response);
10259 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210260 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10261 EXPECT_FALSE(response->was_fetched_via_spdy);
10262 EXPECT_FALSE(response->was_npn_negotiated);
10263
10264 std::string response_data;
10265 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10266 EXPECT_EQ("hello world", response_data);
10267
10268 alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610269 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210270 ASSERT_EQ(2u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:3810271 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:5210272 alternative_service_vector[0].protocol);
10273 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
10274 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc3f0118e2016-02-02 15:42:2210275 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
10276 alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:5210277 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
10278 EXPECT_EQ(1234, alternative_service_vector[1].port);
10279}
10280
bncf33fb31b2016-01-29 15:22:2610281// When |enable_alternative_service_with_different_host| is false, do not
10282// observe alternative service entries that point to a different host.
bnc54ec34b72015-08-26 19:34:5610283TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
bncf33fb31b2016-01-29 15:22:2610284 session_deps_.enable_alternative_service_with_different_host = false;
bnc54ec34b72015-08-26 19:34:5610285
10286 HttpRequestInfo request;
10287 request.method = "GET";
10288 request.url = GURL("http://www.example.org/");
10289 request.load_flags = 0;
10290
10291 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10292 StaticSocketDataProvider first_data;
10293 first_data.set_connect_data(mock_connect);
10294 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10295
10296 MockRead data_reads[] = {
10297 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10298 MockRead(ASYNC, OK),
10299 };
10300 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
10301 nullptr, 0);
10302 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10303
danakj1fd259a02016-04-16 03:17:0910304 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:5610305
10306 base::WeakPtr<HttpServerProperties> http_server_properties =
10307 session->http_server_properties();
10308 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810309 AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
10310 80);
bnc54ec34b72015-08-26 19:34:5610311 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10312 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610313 url::SchemeHostPort(request.url), alternative_service, expiration);
bnc54ec34b72015-08-26 19:34:5610314
danakj1fd259a02016-04-16 03:17:0910315 std::unique_ptr<HttpTransaction> trans(
bnc54ec34b72015-08-26 19:34:5610316 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10317 TestCompletionCallback callback;
10318
10319 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10320 // The connetion to origin was refused, and the alternative service should not
10321 // be used (even though mock data are there), therefore the request should
10322 // fail.
10323 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
10324}
10325
zhongyi48704c182015-12-07 07:52:0210326TEST_P(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610327 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210328 HostPortPair alternative("alternative.example.org", 443);
10329 std::string origin_url = "https://origin.example.org:443";
10330 std::string alternative_url = "https://alternative.example.org:443";
10331
10332 // Negotiate HTTP/1.1 with alternative.example.org.
10333 SSLSocketDataProvider ssl(ASYNC, OK);
10334 ssl.SetNextProto(kProtoHTTP11);
10335 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10336
10337 // HTTP/1.1 data for request.
10338 MockWrite http_writes[] = {
10339 MockWrite("GET / HTTP/1.1\r\n"
10340 "Host: alternative.example.org\r\n"
10341 "Connection: keep-alive\r\n\r\n"),
10342 };
10343
10344 MockRead http_reads[] = {
10345 MockRead("HTTP/1.1 200 OK\r\n"
10346 "Content-Type: text/html; charset=iso-8859-1\r\n"
10347 "Content-Length: 40\r\n\r\n"
10348 "first HTTP/1.1 response from alternative"),
10349 };
10350 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10351 http_writes, arraysize(http_writes));
10352 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10353
10354 StaticSocketDataProvider data_refused;
10355 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10356 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10357
zhongyi3d4a55e72016-04-22 20:36:4610358 // Set up a QUIC alternative service for server.
bncf33fb31b2016-01-29 15:22:2610359 session_deps_.enable_alternative_service_with_different_host = false;
danakj1fd259a02016-04-16 03:17:0910360 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zhongyi48704c182015-12-07 07:52:0210361 base::WeakPtr<HttpServerProperties> http_server_properties =
10362 session->http_server_properties();
10363 AlternativeService alternative_service(QUIC, alternative);
10364 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610365 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010366 expiration);
zhongyi48704c182015-12-07 07:52:0210367 // Mark the QUIC alternative service as broken.
10368 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10369
danakj1fd259a02016-04-16 03:17:0910370 std::unique_ptr<HttpTransaction> trans(
zhongyi48704c182015-12-07 07:52:0210371 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10372 HttpRequestInfo request;
10373 request.method = "GET";
10374 request.url = GURL(origin_url);
10375 request.load_flags = 0;
10376 TestCompletionCallback callback;
10377 NetErrorDetails details;
10378 EXPECT_FALSE(details.quic_broken);
10379
10380 trans->Start(&request, callback.callback(), BoundNetLog());
10381 trans->PopulateNetErrorDetails(&details);
10382 EXPECT_TRUE(details.quic_broken);
10383}
10384
10385TEST_P(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610386 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210387 HostPortPair alternative1("alternative1.example.org", 443);
10388 HostPortPair alternative2("alternative2.example.org", 443);
10389 std::string origin_url = "https://origin.example.org:443";
10390 std::string alternative_url1 = "https://alternative1.example.org:443";
10391 std::string alternative_url2 = "https://alternative2.example.org:443";
10392
10393 // Negotiate HTTP/1.1 with alternative1.example.org.
10394 SSLSocketDataProvider ssl(ASYNC, OK);
10395 ssl.SetNextProto(kProtoHTTP11);
10396 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10397
10398 // HTTP/1.1 data for request.
10399 MockWrite http_writes[] = {
10400 MockWrite("GET / HTTP/1.1\r\n"
10401 "Host: alternative1.example.org\r\n"
10402 "Connection: keep-alive\r\n\r\n"),
10403 };
10404
10405 MockRead http_reads[] = {
10406 MockRead("HTTP/1.1 200 OK\r\n"
10407 "Content-Type: text/html; charset=iso-8859-1\r\n"
10408 "Content-Length: 40\r\n\r\n"
10409 "first HTTP/1.1 response from alternative1"),
10410 };
10411 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10412 http_writes, arraysize(http_writes));
10413 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10414
10415 StaticSocketDataProvider data_refused;
10416 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10417 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10418
bncf33fb31b2016-01-29 15:22:2610419 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0910420 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zhongyi48704c182015-12-07 07:52:0210421 base::WeakPtr<HttpServerProperties> http_server_properties =
10422 session->http_server_properties();
10423
zhongyi3d4a55e72016-04-22 20:36:4610424 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210425 AlternativeServiceInfoVector alternative_service_info_vector;
10426 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10427
10428 AlternativeService alternative_service1(QUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010429 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210430 expiration);
10431 alternative_service_info_vector.push_back(alternative_service_info1);
10432 AlternativeService alternative_service2(QUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010433 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210434 expiration);
10435 alternative_service_info_vector.push_back(alternative_service_info2);
10436
10437 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610438 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210439
10440 // Mark one of the QUIC alternative service as broken.
10441 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10442
10443 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610444 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:0210445
danakj1fd259a02016-04-16 03:17:0910446 std::unique_ptr<HttpTransaction> trans(
zhongyi48704c182015-12-07 07:52:0210447 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10448 HttpRequestInfo request;
10449 request.method = "GET";
10450 request.url = GURL(origin_url);
10451 request.load_flags = 0;
10452 TestCompletionCallback callback;
10453 NetErrorDetails details;
10454 EXPECT_FALSE(details.quic_broken);
10455
10456 trans->Start(&request, callback.callback(), BoundNetLog());
10457 trans->PopulateNetErrorDetails(&details);
10458 EXPECT_FALSE(details.quic_broken);
10459}
10460
[email protected]23e482282013-06-14 16:08:0210461TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310462 MarkBrokenAlternateProtocolAndFallback) {
bncf33fb31b2016-01-29 15:22:2610463 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]564b4912010-03-09 16:30:4210464
10465 HttpRequestInfo request;
10466 request.method = "GET";
bncce36dca22015-04-21 22:11:2310467 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210468 request.load_flags = 0;
10469
[email protected]d973e99a2012-02-17 21:02:3610470 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210471 StaticSocketDataProvider first_data;
10472 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710473 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:4210474
10475 MockRead data_reads[] = {
10476 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10477 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610478 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210479 };
10480 StaticSocketDataProvider second_data(
10481 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710482 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210483
danakj1fd259a02016-04-16 03:17:0910484 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210485
[email protected]30d4c022013-07-18 22:58:1610486 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310487 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610488 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110489 // Port must be < 1024, or the header will be ignored (since initial port was
10490 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010491 const AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810492 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bncd9b132e2015-07-08 05:16:1010493 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210494 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610495 http_server_properties->SetAlternativeService(server, alternative_service,
10496 expiration);
[email protected]564b4912010-03-09 16:30:4210497
danakj1fd259a02016-04-16 03:17:0910498 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010499 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110500 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210501
[email protected]49639fa2011-12-20 23:22:4110502 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:4210503 EXPECT_EQ(ERR_IO_PENDING, rv);
10504 EXPECT_EQ(OK, callback.WaitForResult());
10505
10506 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210507 ASSERT_TRUE(response);
10508 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210509 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10510
10511 std::string response_data;
10512 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10513 EXPECT_EQ("hello world", response_data);
10514
bncd9b132e2015-07-08 05:16:1010515 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610516 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010517 ASSERT_EQ(1u, alternative_service_vector.size());
10518 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10519 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10520 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210521}
10522
bnc55ff9da2015-08-19 18:42:3510523// Ensure that we are not allowed to redirect traffic via an alternate protocol
10524// to an unrestricted (port >= 1024) when the original traffic was on a
10525// restricted port (port < 1024). Ensure that we can redirect in all other
10526// cases.
[email protected]23e482282013-06-14 16:08:0210527TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310528 AlternateProtocolPortRestrictedBlocked) {
bncf33fb31b2016-01-29 15:22:2610529 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110530
10531 HttpRequestInfo restricted_port_request;
10532 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310533 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110534 restricted_port_request.load_flags = 0;
10535
[email protected]d973e99a2012-02-17 21:02:3610536 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110537 StaticSocketDataProvider first_data;
10538 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710539 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110540
10541 MockRead data_reads[] = {
10542 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10543 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610544 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110545 };
10546 StaticSocketDataProvider second_data(
10547 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710548 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110549
danakj1fd259a02016-04-16 03:17:0910550 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110551
[email protected]30d4c022013-07-18 22:58:1610552 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310553 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110554 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210555 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810556 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210557 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210558 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210559 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610560 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010561 expiration);
[email protected]3912662a32011-10-04 00:51:1110562
danakj1fd259a02016-04-16 03:17:0910563 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010564 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110565 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110566
[email protected]49639fa2011-12-20 23:22:4110567 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610568 &restricted_port_request,
10569 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110570 EXPECT_EQ(ERR_IO_PENDING, rv);
10571 // Invalid change to unrestricted port should fail.
10572 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:1910573}
[email protected]3912662a32011-10-04 00:51:1110574
bnc55ff9da2015-08-19 18:42:3510575// Ensure that we are allowed to redirect traffic via an alternate protocol to
10576// an unrestricted (port >= 1024) when the original traffic was on a restricted
10577// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:0210578TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:1910579 AlternateProtocolPortRestrictedPermitted) {
bncf33fb31b2016-01-29 15:22:2610580 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]bb88e1d32013-05-03 23:11:0710581 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910582
10583 HttpRequestInfo restricted_port_request;
10584 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310585 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910586 restricted_port_request.load_flags = 0;
10587
10588 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10589 StaticSocketDataProvider first_data;
10590 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710591 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910592
10593 MockRead data_reads[] = {
10594 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10595 MockRead("hello world"),
10596 MockRead(ASYNC, OK),
10597 };
10598 StaticSocketDataProvider second_data(
10599 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710600 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:1910601
danakj1fd259a02016-04-16 03:17:0910602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910603
[email protected]30d4c022013-07-18 22:58:1610604 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910605 session->http_server_properties();
10606 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210607 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810608 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210609 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210610 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210611 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610612 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010613 expiration);
[email protected]c54c6962013-02-01 04:53:1910614
danakj1fd259a02016-04-16 03:17:0910615 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010616 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:1910617 TestCompletionCallback callback;
10618
10619 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:3610620 &restricted_port_request,
10621 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:1910622 // Change to unrestricted port should succeed.
10623 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110624}
10625
bnc55ff9da2015-08-19 18:42:3510626// Ensure that we are not allowed to redirect traffic via an alternate protocol
10627// to an unrestricted (port >= 1024) when the original traffic was on a
10628// restricted port (port < 1024). Ensure that we can redirect in all other
10629// cases.
[email protected]23e482282013-06-14 16:08:0210630TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310631 AlternateProtocolPortRestrictedAllowed) {
bncf33fb31b2016-01-29 15:22:2610632 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110633
10634 HttpRequestInfo restricted_port_request;
10635 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310636 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110637 restricted_port_request.load_flags = 0;
10638
[email protected]d973e99a2012-02-17 21:02:3610639 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110640 StaticSocketDataProvider first_data;
10641 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710642 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110643
10644 MockRead data_reads[] = {
10645 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10646 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610647 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110648 };
10649 StaticSocketDataProvider second_data(
10650 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710651 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110652
danakj1fd259a02016-04-16 03:17:0910653 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110654
[email protected]30d4c022013-07-18 22:58:1610655 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310656 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110657 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210658 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810659 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210660 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210661 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210662 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610663 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010664 expiration);
[email protected]3912662a32011-10-04 00:51:1110665
danakj1fd259a02016-04-16 03:17:0910666 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010667 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110668 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110669
[email protected]49639fa2011-12-20 23:22:4110670 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610671 &restricted_port_request,
10672 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110673 EXPECT_EQ(ERR_IO_PENDING, rv);
10674 // Valid change to restricted port should pass.
10675 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110676}
10677
bnc55ff9da2015-08-19 18:42:3510678// Ensure that we are not allowed to redirect traffic via an alternate protocol
10679// to an unrestricted (port >= 1024) when the original traffic was on a
10680// restricted port (port < 1024). Ensure that we can redirect in all other
10681// cases.
[email protected]23e482282013-06-14 16:08:0210682TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310683 AlternateProtocolPortUnrestrictedAllowed1) {
bncf33fb31b2016-01-29 15:22:2610684 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110685
10686 HttpRequestInfo unrestricted_port_request;
10687 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310688 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110689 unrestricted_port_request.load_flags = 0;
10690
[email protected]d973e99a2012-02-17 21:02:3610691 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110692 StaticSocketDataProvider first_data;
10693 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710694 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110695
10696 MockRead data_reads[] = {
10697 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10698 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610699 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110700 };
10701 StaticSocketDataProvider second_data(
10702 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710703 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110704
danakj1fd259a02016-04-16 03:17:0910705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110706
[email protected]30d4c022013-07-18 22:58:1610707 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310708 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110709 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210710 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810711 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210712 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210713 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210714 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610715 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010716 expiration);
[email protected]3912662a32011-10-04 00:51:1110717
danakj1fd259a02016-04-16 03:17:0910718 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010719 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110720 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110721
[email protected]49639fa2011-12-20 23:22:4110722 int rv = trans->Start(
10723 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110724 EXPECT_EQ(ERR_IO_PENDING, rv);
10725 // Valid change to restricted port should pass.
10726 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110727}
10728
bnc55ff9da2015-08-19 18:42:3510729// Ensure that we are not allowed to redirect traffic via an alternate protocol
10730// to an unrestricted (port >= 1024) when the original traffic was on a
10731// restricted port (port < 1024). Ensure that we can redirect in all other
10732// cases.
[email protected]23e482282013-06-14 16:08:0210733TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310734 AlternateProtocolPortUnrestrictedAllowed2) {
bncf33fb31b2016-01-29 15:22:2610735 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110736
10737 HttpRequestInfo unrestricted_port_request;
10738 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310739 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110740 unrestricted_port_request.load_flags = 0;
10741
[email protected]d973e99a2012-02-17 21:02:3610742 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110743 StaticSocketDataProvider first_data;
10744 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710745 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110746
10747 MockRead data_reads[] = {
10748 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10749 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610750 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110751 };
10752 StaticSocketDataProvider second_data(
10753 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710754 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110755
danakj1fd259a02016-04-16 03:17:0910756 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110757
[email protected]30d4c022013-07-18 22:58:1610758 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310759 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210760 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:2210761 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810762 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210763 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210764 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210765 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610766 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010767 expiration);
[email protected]3912662a32011-10-04 00:51:1110768
danakj1fd259a02016-04-16 03:17:0910769 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110771 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110772
[email protected]49639fa2011-12-20 23:22:4110773 int rv = trans->Start(
10774 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110775 EXPECT_EQ(ERR_IO_PENDING, rv);
10776 // Valid change to an unrestricted port should pass.
10777 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110778}
10779
bnc55ff9da2015-08-19 18:42:3510780// Ensure that we are not allowed to redirect traffic via an alternate protocol
10781// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10782// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:2310783TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bncf33fb31b2016-01-29 15:22:2610784 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]eb6234e2012-01-19 01:50:0210785
10786 HttpRequestInfo request;
10787 request.method = "GET";
bncce36dca22015-04-21 22:11:2310788 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210789 request.load_flags = 0;
10790
10791 // The alternate protocol request will error out before we attempt to connect,
10792 // so only the standard HTTP request will try to connect.
10793 MockRead data_reads[] = {
10794 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10795 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610796 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210797 };
10798 StaticSocketDataProvider data(
10799 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710800 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210801
danakj1fd259a02016-04-16 03:17:0910802 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210803
[email protected]30d4c022013-07-18 22:58:1610804 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210805 session->http_server_properties();
10806 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:2210807 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810808 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210809 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210810 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210811 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610812 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210813
danakj1fd259a02016-04-16 03:17:0910814 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010815 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:0210816 TestCompletionCallback callback;
10817
10818 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10819 EXPECT_EQ(ERR_IO_PENDING, rv);
10820 // The HTTP request should succeed.
10821 EXPECT_EQ(OK, callback.WaitForResult());
10822
[email protected]eb6234e2012-01-19 01:50:0210823 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210824 ASSERT_TRUE(response);
10825 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210826 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10827
10828 std::string response_data;
10829 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10830 EXPECT_EQ("hello world", response_data);
10831}
10832
[email protected]23e482282013-06-14 16:08:0210833TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc1c196c6e2016-05-28 13:51:4810834 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2ff8b312010-04-26 22:20:5410835
10836 HttpRequestInfo request;
10837 request.method = "GET";
bncce36dca22015-04-21 22:11:2310838 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410839 request.load_flags = 0;
10840
bnc1c196c6e2016-05-28 13:51:4810841 std::string alternative_service_http_header =
10842 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310843
[email protected]2ff8b312010-04-26 22:20:5410844 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210845 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810846 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210847 MockRead("\r\n"),
10848 MockRead("hello world"),
10849 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10850 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410851
10852 StaticSocketDataProvider first_transaction(
10853 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710854 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410855
[email protected]8ddf8322012-02-23 18:08:0610856 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810857 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310858 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10859 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410861
danakj1fd259a02016-04-16 03:17:0910862 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4910863 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310864 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410865
danakj1fd259a02016-04-16 03:17:0910866 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5510867 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910868 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5510869 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410870 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310871 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410872 };
10873
rch8e6c6c42015-05-01 14:05:1310874 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10875 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710876 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410877
[email protected]d973e99a2012-02-17 21:02:3610878 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510879 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10880 NULL, 0, NULL, 0);
10881 hanging_non_alternate_protocol_socket.set_connect_data(
10882 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710883 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510884 &hanging_non_alternate_protocol_socket);
10885
[email protected]49639fa2011-12-20 23:22:4110886 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410887
danakj1fd259a02016-04-16 03:17:0910888 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10889 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010890 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410891
[email protected]49639fa2011-12-20 23:22:4110892 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410893 EXPECT_EQ(ERR_IO_PENDING, rv);
10894 EXPECT_EQ(OK, callback.WaitForResult());
10895
10896 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210897 ASSERT_TRUE(response);
10898 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410899 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10900
10901 std::string response_data;
10902 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10903 EXPECT_EQ("hello world", response_data);
10904
[email protected]90499482013-06-01 00:39:5010905 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410906
[email protected]49639fa2011-12-20 23:22:4110907 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410908 EXPECT_EQ(ERR_IO_PENDING, rv);
10909 EXPECT_EQ(OK, callback.WaitForResult());
10910
10911 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210912 ASSERT_TRUE(response);
10913 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210914 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310915 EXPECT_TRUE(response->was_fetched_via_spdy);
10916 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410917
10918 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10919 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410920}
10921
[email protected]23e482282013-06-14 16:08:0210922TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc1c196c6e2016-05-28 13:51:4810923 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2d6728692011-03-12 01:39:5510924
10925 HttpRequestInfo request;
10926 request.method = "GET";
bncce36dca22015-04-21 22:11:2310927 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510928 request.load_flags = 0;
10929
bnc1c196c6e2016-05-28 13:51:4810930 std::string alternative_service_http_header =
10931 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310932
[email protected]2d6728692011-03-12 01:39:5510933 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210934 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810935 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210936 MockRead("\r\n"),
10937 MockRead("hello world"),
10938 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10939 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510940 };
10941
10942 StaticSocketDataProvider first_transaction(
10943 data_reads, arraysize(data_reads), NULL, 0);
10944 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:0710945 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510946
[email protected]d973e99a2012-02-17 21:02:3610947 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810948 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10949 hanging_socket1.set_connect_data(never_finishing_connect);
[email protected]2d6728692011-03-12 01:39:5510950 // Socket 2 and 3 are the hanging Alternate-Protocol and
10951 // non-Alternate-Protocol jobs from the 2nd transaction.
mmenkecc2298e2015-12-07 18:20:1810952 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10953
10954 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10955 hanging_socket2.set_connect_data(never_finishing_connect);
10956 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510957
[email protected]8ddf8322012-02-23 18:08:0610958 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810959 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310960 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5210961 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0710962 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510963
danakj1fd259a02016-04-16 03:17:0910964 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4910965 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
danakj1fd259a02016-04-16 03:17:0910966 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4910967 spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:5510968 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310969 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:5510970 };
danakj1fd259a02016-04-16 03:17:0910971 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5510972 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910973 std::unique_ptr<SpdySerializedFrame> data1(
bncb03b1092016-04-06 11:19:5510974 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0910975 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5510976 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0910977 std::unique_ptr<SpdySerializedFrame> data2(
bncb03b1092016-04-06 11:19:5510978 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510979 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310980 CreateMockRead(*resp1, 2),
10981 CreateMockRead(*data1, 3),
10982 CreateMockRead(*resp2, 4),
10983 CreateMockRead(*data2, 5),
10984 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510985 };
10986
rch8e6c6c42015-05-01 14:05:1310987 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10988 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:5510989 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710990 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510991
10992 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
mmenkecc2298e2015-12-07 18:20:1810993 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10994 hanging_socket3.set_connect_data(never_finishing_connect);
10995 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510996
danakj1fd259a02016-04-16 03:17:0910997 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110998 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010999 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5511000
[email protected]49639fa2011-12-20 23:22:4111001 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511002 EXPECT_EQ(ERR_IO_PENDING, rv);
11003 EXPECT_EQ(OK, callback1.WaitForResult());
11004
11005 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211006 ASSERT_TRUE(response);
11007 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511008 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11009
11010 std::string response_data;
11011 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11012 EXPECT_EQ("hello world", response_data);
11013
[email protected]49639fa2011-12-20 23:22:4111014 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011015 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111016 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511017 EXPECT_EQ(ERR_IO_PENDING, rv);
11018
[email protected]49639fa2011-12-20 23:22:4111019 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011020 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111021 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511022 EXPECT_EQ(ERR_IO_PENDING, rv);
11023
11024 EXPECT_EQ(OK, callback2.WaitForResult());
11025 EXPECT_EQ(OK, callback3.WaitForResult());
11026
11027 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211028 ASSERT_TRUE(response);
11029 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211030 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511031 EXPECT_TRUE(response->was_fetched_via_spdy);
11032 EXPECT_TRUE(response->was_npn_negotiated);
11033 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11034 EXPECT_EQ("hello!", response_data);
11035
11036 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211037 ASSERT_TRUE(response);
11038 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211039 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511040 EXPECT_TRUE(response->was_fetched_via_spdy);
11041 EXPECT_TRUE(response->was_npn_negotiated);
11042 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
11043 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511044}
11045
bnc1c196c6e2016-05-28 13:51:4811046TEST_P(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
11047 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2d6728692011-03-12 01:39:5511048
11049 HttpRequestInfo request;
11050 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2511051 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511052 request.load_flags = 0;
11053
bnc1c196c6e2016-05-28 13:51:4811054 std::string alternative_service_http_header =
11055 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4311056
[email protected]2d6728692011-03-12 01:39:5511057 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211058 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4811059 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5211060 MockRead("\r\n"),
11061 MockRead("hello world"),
11062 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11063 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511064 };
11065
11066 StaticSocketDataProvider first_transaction(
11067 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711068 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511069
[email protected]8ddf8322012-02-23 18:08:0611070 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811071 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0711072 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511073
[email protected]d973e99a2012-02-17 21:02:3611074 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511075 StaticSocketDataProvider hanging_alternate_protocol_socket(
11076 NULL, 0, NULL, 0);
11077 hanging_alternate_protocol_socket.set_connect_data(
11078 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711079 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511080 &hanging_alternate_protocol_socket);
11081
11082 // 2nd request is just a copy of the first one, over HTTP again.
mmenkecc2298e2015-12-07 18:20:1811083 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11084 NULL, 0);
11085 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
[email protected]2d6728692011-03-12 01:39:5511086
[email protected]49639fa2011-12-20 23:22:4111087 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511088
danakj1fd259a02016-04-16 03:17:0911089 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11090 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011091 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511092
[email protected]49639fa2011-12-20 23:22:4111093 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511094 EXPECT_EQ(ERR_IO_PENDING, rv);
11095 EXPECT_EQ(OK, callback.WaitForResult());
11096
11097 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211098 ASSERT_TRUE(response);
11099 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511100 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11101
11102 std::string response_data;
11103 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11104 EXPECT_EQ("hello world", response_data);
11105
[email protected]90499482013-06-01 00:39:5011106 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511107
[email protected]49639fa2011-12-20 23:22:4111108 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511109 EXPECT_EQ(ERR_IO_PENDING, rv);
11110 EXPECT_EQ(OK, callback.WaitForResult());
11111
11112 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211113 ASSERT_TRUE(response);
11114 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511115 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11116 EXPECT_FALSE(response->was_fetched_via_spdy);
11117 EXPECT_FALSE(response->was_npn_negotiated);
11118
11119 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11120 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511121}
11122
[email protected]631f1322010-04-30 17:59:1111123class CapturingProxyResolver : public ProxyResolver {
11124 public:
sammce90c9212015-05-27 23:43:3511125 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011126 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111127
dchengb03027d2014-10-21 12:00:2011128 int GetProxyForURL(const GURL& url,
11129 ProxyInfo* results,
11130 const CompletionCallback& callback,
eroman9c8f4242016-02-29 21:16:5411131 RequestHandle* request,
dchengb03027d2014-10-21 12:00:2011132 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011133 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11134 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211135 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111136 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211137 return OK;
[email protected]631f1322010-04-30 17:59:1111138 }
11139
eroman9c8f4242016-02-29 21:16:5411140 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
11141
11142 LoadState GetLoadState(RequestHandle request) const override {
11143 NOTREACHED();
11144 return LOAD_STATE_IDLE;
11145 }
11146
[email protected]24476402010-07-20 20:55:1711147 const std::vector<GURL>& resolved() const { return resolved_; }
11148
11149 private:
[email protected]631f1322010-04-30 17:59:1111150 std::vector<GURL> resolved_;
11151
11152 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11153};
11154
sammce64b2362015-04-29 03:50:2311155class CapturingProxyResolverFactory : public ProxyResolverFactory {
11156 public:
11157 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11158 : ProxyResolverFactory(false), resolver_(resolver) {}
11159
11160 int CreateProxyResolver(
11161 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911162 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311163 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911164 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2311165 resolver->reset(new ForwardingProxyResolver(resolver_));
11166 return OK;
11167 }
11168
11169 private:
11170 ProxyResolver* resolver_;
11171};
11172
bnc1c196c6e2016-05-28 13:51:4811173TEST_P(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
11174 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]631f1322010-04-30 17:59:1111175
11176 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211177 proxy_config.set_auto_detect(true);
11178 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111179
sammc5dd160c2015-04-02 02:43:1311180 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711181 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0911182 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)),
11183 base::WrapUnique(
sammce64b2362015-04-29 03:50:2311184 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:3811185 NULL));
vishal.b62985ca92015-04-17 08:45:5111186 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711187 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111188
11189 HttpRequestInfo request;
11190 request.method = "GET";
bncce36dca22015-04-21 22:11:2311191 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111192 request.load_flags = 0;
11193
bnc1c196c6e2016-05-28 13:51:4811194 std::string alternative_service_http_header =
11195 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4311196
[email protected]631f1322010-04-30 17:59:1111197 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211198 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4811199 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5211200 MockRead("\r\n"),
11201 MockRead("hello world"),
11202 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11203 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111204 };
11205
11206 StaticSocketDataProvider first_transaction(
11207 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711208 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1111209
[email protected]8ddf8322012-02-23 18:08:0611210 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811211 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2311212 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5211213 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0711214 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1111215
danakj1fd259a02016-04-16 03:17:0911216 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911217 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1111218 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311219 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511220 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11221 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311222 "Proxy-Connection: keep-alive\r\n\r\n"),
11223 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1111224 };
11225
[email protected]d911f1b2010-05-05 22:39:4211226 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11227
danakj1fd259a02016-04-16 03:17:0911228 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5511229 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0911230 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5511231 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111232 MockRead spdy_reads[] = {
mmenkee24011922015-12-17 22:12:5911233 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(*resp.get(), 3),
11234 CreateMockRead(*data.get(), 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111235 };
11236
rch8e6c6c42015-05-01 14:05:1311237 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11238 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711239 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111240
[email protected]d973e99a2012-02-17 21:02:3611241 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511242 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11243 NULL, 0, NULL, 0);
11244 hanging_non_alternate_protocol_socket.set_connect_data(
11245 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711246 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511247 &hanging_non_alternate_protocol_socket);
11248
[email protected]49639fa2011-12-20 23:22:4111249 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111250
danakj1fd259a02016-04-16 03:17:0911251 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11252 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011253 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111254
[email protected]49639fa2011-12-20 23:22:4111255 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1111256 EXPECT_EQ(ERR_IO_PENDING, rv);
11257 EXPECT_EQ(OK, callback.WaitForResult());
11258
11259 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211260 ASSERT_TRUE(response);
11261 ASSERT_TRUE(response->headers);
[email protected]631f1322010-04-30 17:59:1111262 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311263 EXPECT_FALSE(response->was_fetched_via_spdy);
11264 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1111265
11266 std::string response_data;
11267 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11268 EXPECT_EQ("hello world", response_data);
11269
[email protected]90499482013-06-01 00:39:5011270 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111271
[email protected]49639fa2011-12-20 23:22:4111272 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1111273 EXPECT_EQ(ERR_IO_PENDING, rv);
11274 EXPECT_EQ(OK, callback.WaitForResult());
11275
11276 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211277 ASSERT_TRUE(response);
11278 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211279 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311280 EXPECT_TRUE(response->was_fetched_via_spdy);
11281 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1111282
11283 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11284 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1311285 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2311286 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311287 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311288 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311289 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111290
[email protected]029c83b62013-01-24 05:28:2011291 LoadTimingInfo load_timing_info;
11292 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11293 TestLoadTimingNotReusedWithPac(load_timing_info,
11294 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111295}
[email protected]631f1322010-04-30 17:59:1111296
[email protected]23e482282013-06-14 16:08:0211297TEST_P(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811298 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
11299 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2ff8b312010-04-26 22:20:5411300
11301 HttpRequestInfo request;
11302 request.method = "GET";
bncce36dca22015-04-21 22:11:2311303 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411304 request.load_flags = 0;
11305
bnc1c196c6e2016-05-28 13:51:4811306 std::string alternative_service_http_header =
11307 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4311308
[email protected]2ff8b312010-04-26 22:20:5411309 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211310 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4811311 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5211312 MockRead("\r\n"),
11313 MockRead("hello world"),
11314 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411315 };
11316
11317 StaticSocketDataProvider first_transaction(
11318 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711319 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5411320
[email protected]8ddf8322012-02-23 18:08:0611321 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811322 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2311323 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5211324 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0711325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5411326
danakj1fd259a02016-04-16 03:17:0911327 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911328 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1311329 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411330
danakj1fd259a02016-04-16 03:17:0911331 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5511332 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0911333 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5511334 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411335 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311336 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411337 };
11338
rch8e6c6c42015-05-01 14:05:1311339 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11340 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711341 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411342
[email protected]83039bb2011-12-09 18:43:5511343 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411344
danakj1fd259a02016-04-16 03:17:0911345 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411346
danakj1fd259a02016-04-16 03:17:0911347 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011348 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411349
[email protected]49639fa2011-12-20 23:22:4111350 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5411351 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111352 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5411353
11354 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211355 ASSERT_TRUE(response);
11356 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411357 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11358
11359 std::string response_data;
11360 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11361 EXPECT_EQ("hello world", response_data);
11362
11363 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511364 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011365 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311366 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711367 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4211368 CreateSecureSpdySession(session.get(), key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3811369
[email protected]90499482013-06-01 00:39:5011370 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411371
[email protected]49639fa2011-12-20 23:22:4111372 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5411373 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111374 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5411375
11376 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211377 ASSERT_TRUE(response);
11378 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211379 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311380 EXPECT_TRUE(response->was_fetched_via_spdy);
11381 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411382
11383 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11384 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211385}
11386
[email protected]044de0642010-06-17 10:42:1511387// GenerateAuthToken is a mighty big test.
11388// It tests all permutation of GenerateAuthToken behavior:
11389// - Synchronous and Asynchronous completion.
11390// - OK or error on completion.
11391// - Direct connection, non-authenticating proxy, and authenticating proxy.
11392// - HTTP or HTTPS backend (to include proxy tunneling).
11393// - Non-authenticating and authenticating backend.
11394//
[email protected]fe3b7dc2012-02-03 19:52:0911395// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511396// problems generating an auth token for an authenticating proxy, we don't
11397// need to test all permutations of the backend server).
11398//
11399// The test proceeds by going over each of the configuration cases, and
11400// potentially running up to three rounds in each of the tests. The TestConfig
11401// specifies both the configuration for the test as well as the expectations
11402// for the results.
[email protected]23e482282013-06-14 16:08:0211403TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011404 static const char kServer[] = "http://www.example.com";
11405 static const char kSecureServer[] = "https://www.example.com";
11406 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511407 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
11408
11409 enum AuthTiming {
11410 AUTH_NONE,
11411 AUTH_SYNC,
11412 AUTH_ASYNC,
11413 };
11414
11415 const MockWrite kGet(
11416 "GET / HTTP/1.1\r\n"
11417 "Host: www.example.com\r\n"
11418 "Connection: keep-alive\r\n\r\n");
11419 const MockWrite kGetProxy(
11420 "GET http://www.example.com/ HTTP/1.1\r\n"
11421 "Host: www.example.com\r\n"
11422 "Proxy-Connection: keep-alive\r\n\r\n");
11423 const MockWrite kGetAuth(
11424 "GET / HTTP/1.1\r\n"
11425 "Host: www.example.com\r\n"
11426 "Connection: keep-alive\r\n"
11427 "Authorization: auth_token\r\n\r\n");
11428 const MockWrite kGetProxyAuth(
11429 "GET http://www.example.com/ HTTP/1.1\r\n"
11430 "Host: www.example.com\r\n"
11431 "Proxy-Connection: keep-alive\r\n"
11432 "Proxy-Authorization: auth_token\r\n\r\n");
11433 const MockWrite kGetAuthThroughProxy(
11434 "GET http://www.example.com/ HTTP/1.1\r\n"
11435 "Host: www.example.com\r\n"
11436 "Proxy-Connection: keep-alive\r\n"
11437 "Authorization: auth_token\r\n\r\n");
11438 const MockWrite kGetAuthWithProxyAuth(
11439 "GET http://www.example.com/ HTTP/1.1\r\n"
11440 "Host: www.example.com\r\n"
11441 "Proxy-Connection: keep-alive\r\n"
11442 "Proxy-Authorization: auth_token\r\n"
11443 "Authorization: auth_token\r\n\r\n");
11444 const MockWrite kConnect(
11445 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711446 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511447 "Proxy-Connection: keep-alive\r\n\r\n");
11448 const MockWrite kConnectProxyAuth(
11449 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711450 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511451 "Proxy-Connection: keep-alive\r\n"
11452 "Proxy-Authorization: auth_token\r\n\r\n");
11453
11454 const MockRead kSuccess(
11455 "HTTP/1.1 200 OK\r\n"
11456 "Content-Type: text/html; charset=iso-8859-1\r\n"
11457 "Content-Length: 3\r\n\r\n"
11458 "Yes");
11459 const MockRead kFailure(
11460 "Should not be called.");
11461 const MockRead kServerChallenge(
11462 "HTTP/1.1 401 Unauthorized\r\n"
11463 "WWW-Authenticate: Mock realm=server\r\n"
11464 "Content-Type: text/html; charset=iso-8859-1\r\n"
11465 "Content-Length: 14\r\n\r\n"
11466 "Unauthorized\r\n");
11467 const MockRead kProxyChallenge(
11468 "HTTP/1.1 407 Unauthorized\r\n"
11469 "Proxy-Authenticate: Mock realm=proxy\r\n"
11470 "Proxy-Connection: close\r\n"
11471 "Content-Type: text/html; charset=iso-8859-1\r\n"
11472 "Content-Length: 14\r\n\r\n"
11473 "Unauthorized\r\n");
11474 const MockRead kProxyConnected(
11475 "HTTP/1.1 200 Connection Established\r\n\r\n");
11476
11477 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11478 // no constructors, but the C++ compiler on Windows warns about
11479 // unspecified data in compound literals. So, moved to using constructors,
11480 // and TestRound's created with the default constructor should not be used.
11481 struct TestRound {
11482 TestRound()
11483 : expected_rv(ERR_UNEXPECTED),
11484 extra_write(NULL),
11485 extra_read(NULL) {
11486 }
11487 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11488 int expected_rv_arg)
11489 : write(write_arg),
11490 read(read_arg),
11491 expected_rv(expected_rv_arg),
11492 extra_write(NULL),
11493 extra_read(NULL) {
11494 }
11495 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11496 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111497 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511498 : write(write_arg),
11499 read(read_arg),
11500 expected_rv(expected_rv_arg),
11501 extra_write(extra_write_arg),
11502 extra_read(extra_read_arg) {
11503 }
11504 MockWrite write;
11505 MockRead read;
11506 int expected_rv;
11507 const MockWrite* extra_write;
11508 const MockRead* extra_read;
11509 };
11510
11511 static const int kNoSSL = 500;
11512
11513 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5111514 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511515 AuthTiming proxy_auth_timing;
11516 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5111517 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511518 AuthTiming server_auth_timing;
11519 int server_auth_rv;
11520 int num_auth_rounds;
11521 int first_ssl_round;
11522 TestRound rounds[3];
11523 } test_configs[] = {
11524 // Non-authenticating HTTP server with a direct connection.
11525 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11526 { TestRound(kGet, kSuccess, OK)}},
11527 // Authenticating HTTP server with a direct connection.
11528 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11529 { TestRound(kGet, kServerChallenge, OK),
11530 TestRound(kGetAuth, kSuccess, OK)}},
11531 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11532 { TestRound(kGet, kServerChallenge, OK),
11533 TestRound(kGetAuth, kFailure, kAuthErr)}},
11534 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11535 { TestRound(kGet, kServerChallenge, OK),
11536 TestRound(kGetAuth, kSuccess, OK)}},
11537 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11538 { TestRound(kGet, kServerChallenge, OK),
11539 TestRound(kGetAuth, kFailure, kAuthErr)}},
11540 // Non-authenticating HTTP server through a non-authenticating proxy.
11541 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11542 { TestRound(kGetProxy, kSuccess, OK)}},
11543 // Authenticating HTTP server through a non-authenticating proxy.
11544 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11545 { TestRound(kGetProxy, kServerChallenge, OK),
11546 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11547 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11548 { TestRound(kGetProxy, kServerChallenge, OK),
11549 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11550 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11551 { TestRound(kGetProxy, kServerChallenge, OK),
11552 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11553 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11554 { TestRound(kGetProxy, kServerChallenge, OK),
11555 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11556 // Non-authenticating HTTP server through an authenticating proxy.
11557 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11558 { TestRound(kGetProxy, kProxyChallenge, OK),
11559 TestRound(kGetProxyAuth, kSuccess, OK)}},
11560 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11561 { TestRound(kGetProxy, kProxyChallenge, OK),
11562 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11563 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11564 { TestRound(kGetProxy, kProxyChallenge, OK),
11565 TestRound(kGetProxyAuth, kSuccess, OK)}},
11566 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11567 { TestRound(kGetProxy, kProxyChallenge, OK),
11568 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11569 // Authenticating HTTP server through an authenticating proxy.
11570 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11571 { TestRound(kGetProxy, kProxyChallenge, OK),
11572 TestRound(kGetProxyAuth, kServerChallenge, OK),
11573 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11574 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11575 { TestRound(kGetProxy, kProxyChallenge, OK),
11576 TestRound(kGetProxyAuth, kServerChallenge, OK),
11577 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11578 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11579 { TestRound(kGetProxy, kProxyChallenge, OK),
11580 TestRound(kGetProxyAuth, kServerChallenge, OK),
11581 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11582 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11583 { TestRound(kGetProxy, kProxyChallenge, OK),
11584 TestRound(kGetProxyAuth, kServerChallenge, OK),
11585 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11586 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11587 { TestRound(kGetProxy, kProxyChallenge, OK),
11588 TestRound(kGetProxyAuth, kServerChallenge, OK),
11589 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11590 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11591 { TestRound(kGetProxy, kProxyChallenge, OK),
11592 TestRound(kGetProxyAuth, kServerChallenge, OK),
11593 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11594 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11595 { TestRound(kGetProxy, kProxyChallenge, OK),
11596 TestRound(kGetProxyAuth, kServerChallenge, OK),
11597 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11598 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11599 { TestRound(kGetProxy, kProxyChallenge, OK),
11600 TestRound(kGetProxyAuth, kServerChallenge, OK),
11601 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11602 // Non-authenticating HTTPS server with a direct connection.
11603 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11604 { TestRound(kGet, kSuccess, OK)}},
11605 // Authenticating HTTPS server with a direct connection.
11606 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11607 { TestRound(kGet, kServerChallenge, OK),
11608 TestRound(kGetAuth, kSuccess, OK)}},
11609 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11610 { TestRound(kGet, kServerChallenge, OK),
11611 TestRound(kGetAuth, kFailure, kAuthErr)}},
11612 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11613 { TestRound(kGet, kServerChallenge, OK),
11614 TestRound(kGetAuth, kSuccess, OK)}},
11615 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11616 { TestRound(kGet, kServerChallenge, OK),
11617 TestRound(kGetAuth, kFailure, kAuthErr)}},
11618 // Non-authenticating HTTPS server with a non-authenticating proxy.
11619 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11620 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11621 // Authenticating HTTPS server through a non-authenticating proxy.
11622 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11623 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11624 TestRound(kGetAuth, kSuccess, OK)}},
11625 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11626 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11627 TestRound(kGetAuth, kFailure, kAuthErr)}},
11628 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11629 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11630 TestRound(kGetAuth, kSuccess, OK)}},
11631 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11632 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11633 TestRound(kGetAuth, kFailure, kAuthErr)}},
11634 // Non-Authenticating HTTPS server through an authenticating proxy.
11635 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11636 { TestRound(kConnect, kProxyChallenge, OK),
11637 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11638 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11639 { TestRound(kConnect, kProxyChallenge, OK),
11640 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11641 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11642 { TestRound(kConnect, kProxyChallenge, OK),
11643 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11644 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11645 { TestRound(kConnect, kProxyChallenge, OK),
11646 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11647 // Authenticating HTTPS server through an authenticating proxy.
11648 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11649 { TestRound(kConnect, kProxyChallenge, OK),
11650 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11651 &kGet, &kServerChallenge),
11652 TestRound(kGetAuth, kSuccess, OK)}},
11653 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11654 { TestRound(kConnect, kProxyChallenge, OK),
11655 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11656 &kGet, &kServerChallenge),
11657 TestRound(kGetAuth, kFailure, kAuthErr)}},
11658 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11659 { TestRound(kConnect, kProxyChallenge, OK),
11660 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11661 &kGet, &kServerChallenge),
11662 TestRound(kGetAuth, kSuccess, OK)}},
11663 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11664 { TestRound(kConnect, kProxyChallenge, OK),
11665 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11666 &kGet, &kServerChallenge),
11667 TestRound(kGetAuth, kFailure, kAuthErr)}},
11668 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11669 { TestRound(kConnect, kProxyChallenge, OK),
11670 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11671 &kGet, &kServerChallenge),
11672 TestRound(kGetAuth, kSuccess, OK)}},
11673 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11674 { TestRound(kConnect, kProxyChallenge, OK),
11675 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11676 &kGet, &kServerChallenge),
11677 TestRound(kGetAuth, kFailure, kAuthErr)}},
11678 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11679 { TestRound(kConnect, kProxyChallenge, OK),
11680 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11681 &kGet, &kServerChallenge),
11682 TestRound(kGetAuth, kSuccess, OK)}},
11683 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11684 { TestRound(kConnect, kProxyChallenge, OK),
11685 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11686 &kGet, &kServerChallenge),
11687 TestRound(kGetAuth, kFailure, kAuthErr)}},
11688 };
11689
viettrungluue4a8b882014-10-16 06:17:3811690 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0811691 HttpAuthHandlerMock::Factory* auth_factory(
11692 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711693 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4911694 SSLInfo empty_ssl_info;
[email protected]044de0642010-06-17 10:42:1511695 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2611696
11697 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1511698 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0811699 for (int n = 0; n < 2; n++) {
11700 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11701 std::string auth_challenge = "Mock realm=proxy";
11702 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2411703 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11704 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0811705 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
asanka5ffd5d72016-03-23 16:20:4911706 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811707 auth_handler->SetGenerateExpectation(
11708 test_config.proxy_auth_timing == AUTH_ASYNC,
11709 test_config.proxy_auth_rv);
11710 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11711 }
[email protected]044de0642010-06-17 10:42:1511712 }
11713 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0011714 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1511715 std::string auth_challenge = "Mock realm=server";
11716 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2411717 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11718 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1511719 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911720 empty_ssl_info, origin, BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511721 auth_handler->SetGenerateExpectation(
11722 test_config.server_auth_timing == AUTH_ASYNC,
11723 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0811724 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1511725 }
11726 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0311727 session_deps_.proxy_service =
11728 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1511729 } else {
rdsmith82957ad2015-09-16 19:42:0311730 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1511731 }
11732
11733 HttpRequestInfo request;
11734 request.method = "GET";
11735 request.url = GURL(test_config.server_url);
11736 request.load_flags = 0;
11737
danakj1fd259a02016-04-16 03:17:0911738 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1511739
rchcb68dc62015-05-21 04:45:3611740 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
11741
11742 std::vector<std::vector<MockRead>> mock_reads(1);
11743 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1511744 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11745 const TestRound& read_write_round = test_config.rounds[round];
11746
11747 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3611748 mock_reads.back().push_back(read_write_round.read);
11749 mock_writes.back().push_back(read_write_round.write);
11750
11751 // kProxyChallenge uses Proxy-Connection: close which means that the
11752 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5411753 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3611754 mock_reads.push_back(std::vector<MockRead>());
11755 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1511756 }
11757
rchcb68dc62015-05-21 04:45:3611758 if (read_write_round.extra_read) {
11759 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1511760 }
rchcb68dc62015-05-21 04:45:3611761 if (read_write_round.extra_write) {
11762 mock_writes.back().push_back(*read_write_round.extra_write);
11763 }
[email protected]044de0642010-06-17 10:42:1511764
11765 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1511766 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0711767 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1511768 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3611769 }
[email protected]044de0642010-06-17 10:42:1511770
danakj1fd259a02016-04-16 03:17:0911771 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3611772 for (size_t i = 0; i < mock_reads.size(); ++i) {
danakj1fd259a02016-04-16 03:17:0911773 data_providers.push_back(base::WrapUnique(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5411774 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3211775 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3611776 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3211777 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3611778 }
11779
mmenkecc2298e2015-12-07 18:20:1811780 // Transaction must be created after DataProviders, so it's destroyed before
11781 // they are as well.
11782 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11783
rchcb68dc62015-05-21 04:45:3611784 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11785 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1511786 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4111787 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1511788 int rv;
11789 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4111790 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511791 } else {
[email protected]49639fa2011-12-20 23:22:4111792 rv = trans.RestartWithAuth(
11793 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1511794 }
11795 if (rv == ERR_IO_PENDING)
11796 rv = callback.WaitForResult();
11797
11798 // Compare results with expected data.
11799 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5011800 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5511801 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1511802 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
11803 continue;
11804 }
11805 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5211806 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511807 } else {
wezca1070932016-05-26 20:30:5211808 EXPECT_FALSE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511809 }
11810 }
[email protected]e5ae96a2010-04-14 20:12:4511811 }
11812}
11813
[email protected]23e482282013-06-14 16:08:0211814TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1411815 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1411816 HttpAuthHandlerMock::Factory* auth_factory(
11817 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711818 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0311819 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0711820 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
11821 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1411822
11823 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11824 auth_handler->set_connection_based(true);
11825 std::string auth_challenge = "Mock realm=server";
11826 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2411827 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11828 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4911829 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1411830 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911831 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811832 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1411833
[email protected]c871bce92010-07-15 21:51:1411834 int rv = OK;
11835 const HttpResponseInfo* response = NULL;
11836 HttpRequestInfo request;
11837 request.method = "GET";
11838 request.url = origin;
11839 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2711840
danakj1fd259a02016-04-16 03:17:0911841 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1011842
11843 // Use a TCP Socket Pool with only one connection per group. This is used
11844 // to validate that the TCP socket is not released to the pool between
11845 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4211846 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2811847 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1011848 50, // Max sockets for pool
11849 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2111850 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
11851 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0911852 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4411853 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0211854 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4811855 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1011856
danakj1fd259a02016-04-16 03:17:0911857 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011858 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111859 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1411860
11861 const MockWrite kGet(
11862 "GET / HTTP/1.1\r\n"
11863 "Host: www.example.com\r\n"
11864 "Connection: keep-alive\r\n\r\n");
11865 const MockWrite kGetAuth(
11866 "GET / HTTP/1.1\r\n"
11867 "Host: www.example.com\r\n"
11868 "Connection: keep-alive\r\n"
11869 "Authorization: auth_token\r\n\r\n");
11870
11871 const MockRead kServerChallenge(
11872 "HTTP/1.1 401 Unauthorized\r\n"
11873 "WWW-Authenticate: Mock realm=server\r\n"
11874 "Content-Type: text/html; charset=iso-8859-1\r\n"
11875 "Content-Length: 14\r\n\r\n"
11876 "Unauthorized\r\n");
11877 const MockRead kSuccess(
11878 "HTTP/1.1 200 OK\r\n"
11879 "Content-Type: text/html; charset=iso-8859-1\r\n"
11880 "Content-Length: 3\r\n\r\n"
11881 "Yes");
11882
11883 MockWrite writes[] = {
11884 // First round
11885 kGet,
11886 // Second round
11887 kGetAuth,
11888 // Third round
11889 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3011890 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1011891 kGetAuth,
11892 // Competing request
11893 kGet,
[email protected]c871bce92010-07-15 21:51:1411894 };
11895 MockRead reads[] = {
11896 // First round
11897 kServerChallenge,
11898 // Second round
11899 kServerChallenge,
11900 // Third round
[email protected]eca50e122010-09-11 14:03:3011901 kServerChallenge,
11902 // Fourth round
[email protected]c871bce92010-07-15 21:51:1411903 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1011904 // Competing response
11905 kSuccess,
[email protected]c871bce92010-07-15 21:51:1411906 };
11907 StaticSocketDataProvider data_provider(reads, arraysize(reads),
11908 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0711909 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1411910
thestig9d3bb0c2015-01-24 00:49:5111911 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1011912
11913 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1411914 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111915 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1411916 if (rv == ERR_IO_PENDING)
11917 rv = callback.WaitForResult();
11918 EXPECT_EQ(OK, rv);
11919 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211920 ASSERT_TRUE(response);
11921 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811922 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411923
[email protected]7ef4cbbb2011-02-06 11:19:1011924 // In between rounds, another request comes in for the same domain.
11925 // It should not be able to grab the TCP socket that trans has already
11926 // claimed.
danakj1fd259a02016-04-16 03:17:0911927 std::unique_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5011928 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111929 TestCompletionCallback callback_compete;
11930 rv = trans_compete->Start(
11931 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1011932 EXPECT_EQ(ERR_IO_PENDING, rv);
11933 // callback_compete.WaitForResult at this point would stall forever,
11934 // since the HttpNetworkTransaction does not release the request back to
11935 // the pool until after authentication completes.
11936
11937 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1411938 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111939 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411940 if (rv == ERR_IO_PENDING)
11941 rv = callback.WaitForResult();
11942 EXPECT_EQ(OK, rv);
11943 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211944 ASSERT_TRUE(response);
11945 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811946 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411947
[email protected]7ef4cbbb2011-02-06 11:19:1011948 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1411949 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111950 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411951 if (rv == ERR_IO_PENDING)
11952 rv = callback.WaitForResult();
11953 EXPECT_EQ(OK, rv);
11954 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211955 ASSERT_TRUE(response);
11956 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811957 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3011958
[email protected]7ef4cbbb2011-02-06 11:19:1011959 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3011960 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111961 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3011962 if (rv == ERR_IO_PENDING)
11963 rv = callback.WaitForResult();
11964 EXPECT_EQ(OK, rv);
11965 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211966 ASSERT_TRUE(response);
11967 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811968 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011969
11970 // Read the body since the fourth round was successful. This will also
11971 // release the socket back to the pool.
11972 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5011973 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011974 if (rv == ERR_IO_PENDING)
11975 rv = callback.WaitForResult();
11976 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011977 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011978 EXPECT_EQ(0, rv);
11979 // There are still 0 idle sockets, since the trans_compete transaction
11980 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2811981 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011982
11983 // The competing request can now finish. Wait for the headers and then
11984 // read the body.
11985 rv = callback_compete.WaitForResult();
11986 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5011987 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011988 if (rv == ERR_IO_PENDING)
11989 rv = callback.WaitForResult();
11990 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011991 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011992 EXPECT_EQ(0, rv);
11993
11994 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2811995 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411996}
11997
[email protected]65041fa2010-05-21 06:56:5311998// This tests the case that a request is issued via http instead of spdy after
11999// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0212000TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bncf33fb31b2016-01-29 15:22:2612001 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d7599122014-05-24 03:37:2312002
[email protected]65041fa2010-05-21 06:56:5312003 HttpRequestInfo request;
12004 request.method = "GET";
bncce36dca22015-04-21 22:11:2312005 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312006 request.load_flags = 0;
12007
12008 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312009 MockWrite(
12010 "GET / HTTP/1.1\r\n"
12011 "Host: www.example.org\r\n"
12012 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312013 };
12014
bnc1c196c6e2016-05-28 13:51:4812015 std::string alternative_service_http_header =
12016 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4312017
[email protected]65041fa2010-05-21 06:56:5312018 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212019 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4812020 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5212021 MockRead("\r\n"),
12022 MockRead("hello world"),
12023 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312024 };
12025
[email protected]8ddf8322012-02-23 18:08:0612026 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4812027 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5312028
[email protected]bb88e1d32013-05-03 23:11:0712029 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312030
12031 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12032 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712033 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312034
[email protected]49639fa2011-12-20 23:22:4112035 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312036
danakj1fd259a02016-04-16 03:17:0912037 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12038 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012039 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5312040
[email protected]49639fa2011-12-20 23:22:4112041 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5312042
12043 EXPECT_EQ(ERR_IO_PENDING, rv);
12044 EXPECT_EQ(OK, callback.WaitForResult());
12045
12046 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212047 ASSERT_TRUE(response);
12048 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312049 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12050
12051 std::string response_data;
12052 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12053 EXPECT_EQ("hello world", response_data);
12054
12055 EXPECT_FALSE(response->was_fetched_via_spdy);
12056 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312057}
[email protected]26ef6582010-06-24 02:30:4712058
bnc55ff9da2015-08-19 18:42:3512059// Simulate the SSL handshake completing with an NPN negotiation followed by an
12060// immediate server closing of the socket.
12061// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0212062TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bncf33fb31b2016-01-29 15:22:2612063 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]26ef6582010-06-24 02:30:4712064
12065 HttpRequestInfo request;
12066 request.method = "GET";
bncce36dca22015-04-21 22:11:2312067 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712068 request.load_flags = 0;
12069
[email protected]8ddf8322012-02-23 18:08:0612070 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812071 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712072 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712073
danakj1fd259a02016-04-16 03:17:0912074 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912075 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1312076 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4712077
12078 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612079 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712080 };
12081
rch8e6c6c42015-05-01 14:05:1312082 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12083 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712084 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712085
[email protected]49639fa2011-12-20 23:22:4112086 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712087
danakj1fd259a02016-04-16 03:17:0912088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12089 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012090 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4712091
[email protected]49639fa2011-12-20 23:22:4112092 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4712093 EXPECT_EQ(ERR_IO_PENDING, rv);
12094 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4712095}
[email protected]65d34382010-07-01 18:12:2612096
[email protected]795cbf82013-07-22 09:37:2712097// A subclass of HttpAuthHandlerMock that records the request URL when
12098// it gets it. This is needed since the auth handler may get destroyed
12099// before we get a chance to query it.
12100class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12101 public:
12102 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12103
dchengb03027d2014-10-21 12:00:2012104 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712105
12106 protected:
dchengb03027d2014-10-21 12:00:2012107 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12108 const HttpRequestInfo* request,
12109 const CompletionCallback& callback,
12110 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712111 *url_ = request->url;
12112 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12113 credentials, request, callback, auth_token);
12114 }
12115
12116 private:
12117 GURL* url_;
12118};
12119
bnc55ff9da2015-08-19 18:42:3512120// This test ensures that the URL passed into the proxy is upgraded to https
12121// when doing an Alternate Protocol upgrade.
bnc1c196c6e2016-05-28 13:51:4812122TEST_P(HttpNetworkTransactionTest, SpdyAlternativeServiceThroughProxy) {
bncf33fb31b2016-01-29 15:22:2612123 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]f45c1ee2010-08-03 00:54:3012124
rdsmith82957ad2015-09-16 19:42:0312125 session_deps_.proxy_service =
12126 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112127 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712128 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2712129 GURL request_url;
12130 {
12131 HttpAuthHandlerMock::Factory* auth_factory =
12132 new HttpAuthHandlerMock::Factory();
12133 UrlRecordingHttpAuthHandlerMock* auth_handler =
12134 new UrlRecordingHttpAuthHandlerMock(&request_url);
12135 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12136 auth_factory->set_do_init_from_challenge(true);
12137 session_deps_.http_auth_handler_factory.reset(auth_factory);
12138 }
[email protected]f45c1ee2010-08-03 00:54:3012139
12140 HttpRequestInfo request;
12141 request.method = "GET";
bncce36dca22015-04-21 22:11:2312142 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3012143 request.load_flags = 0;
12144
12145 // First round goes unauthenticated through the proxy.
12146 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2312147 MockWrite(
12148 "GET http://www.example.org/ HTTP/1.1\r\n"
12149 "Host: www.example.org\r\n"
12150 "Proxy-Connection: keep-alive\r\n"
12151 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3012152 };
12153 MockRead data_reads_1[] = {
bnc1c196c6e2016-05-28 13:51:4812154 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12155 MockRead("HTTP/1.1 200 OK\r\n"),
12156 MockRead("Alt-Svc: "),
12157 MockRead(GetAlternateProtocolFromParam()),
12158 MockRead("=\":443\"\r\n"),
12159 MockRead("Proxy-Connection: close\r\n"),
12160 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3012161 };
12162 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
12163 data_writes_1, arraysize(data_writes_1));
12164
bncce36dca22015-04-21 22:11:2312165 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3012166 // Alternate-Protocol announcement in the first round. It fails due
12167 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2312168 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5912169 // Proxy-Authorization headers. There is then a SPDY request round.
12170 //
[email protected]fe3b7dc2012-02-03 19:52:0912171 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
12172 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
12173 // does a Disconnect and Connect on the same socket, rather than trying
12174 // to obtain a new one.
12175 //
[email protected]394816e92010-08-03 07:38:5912176 // NOTE: Originally, the proxy response to the second CONNECT request
12177 // simply returned another 407 so the unit test could skip the SSL connection
12178 // establishment and SPDY framing issues. Alas, the
12179 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3012180 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5912181
danakj1fd259a02016-04-16 03:17:0912182 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912183 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
danakj1fd259a02016-04-16 03:17:0912184 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5512185 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912186 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5512187 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3012188
[email protected]394816e92010-08-03 07:38:5912189 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2312190 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1312191 MockWrite(ASYNC, 0,
12192 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712193 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312194 "Proxy-Connection: keep-alive\r\n"
12195 "\r\n"),
[email protected]394816e92010-08-03 07:38:5912196
bncce36dca22015-04-21 22:11:2312197 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1312198 MockWrite(ASYNC, 2,
12199 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712200 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312201 "Proxy-Connection: keep-alive\r\n"
12202 "Proxy-Authorization: auth_token\r\n"
12203 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3012204
bncce36dca22015-04-21 22:11:2312205 // SPDY request
rch8e6c6c42015-05-01 14:05:1312206 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3012207 };
[email protected]394816e92010-08-03 07:38:5912208 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1312209 // First connection attempt fails
mmenkee71e15332015-10-07 16:39:5412210 MockRead(ASYNC, 1,
12211 "HTTP/1.1 407 Unauthorized\r\n"
12212 "Proxy-Authenticate: Mock\r\n"
12213 "Content-Length: 0\r\n"
12214 "Proxy-Connection: keep-alive\r\n"
12215 "\r\n"),
[email protected]394816e92010-08-03 07:38:5912216
rch8e6c6c42015-05-01 14:05:1312217 // Second connection attempt passes
mmenkee71e15332015-10-07 16:39:5412218 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5912219
rch8e6c6c42015-05-01 14:05:1312220 // SPDY response
mmenkee71e15332015-10-07 16:39:5412221 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1312222 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5912223 };
rch8e6c6c42015-05-01 14:05:1312224 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
12225 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3012226
[email protected]8ddf8322012-02-23 18:08:0612227 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812228 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2312229 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5212230 ASSERT_TRUE(ssl.cert);
[email protected]f45c1ee2010-08-03 00:54:3012231
[email protected]d973e99a2012-02-17 21:02:3612232 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512233 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12234 NULL, 0, NULL, 0);
12235 hanging_non_alternate_protocol_socket.set_connect_data(
12236 never_finishing_connect);
12237
[email protected]bb88e1d32013-05-03 23:11:0712238 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
12239 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
12240 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12241 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512242 &hanging_non_alternate_protocol_socket);
danakj1fd259a02016-04-16 03:17:0912243 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3012244
12245 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4112246 TestCompletionCallback callback_1;
danakj1fd259a02016-04-16 03:17:0912247 std::unique_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5012248 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4112249 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3012250 EXPECT_EQ(ERR_IO_PENDING, rv);
12251 EXPECT_EQ(OK, callback_1.WaitForResult());
12252
12253 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4112254 TestCompletionCallback callback_2;
danakj1fd259a02016-04-16 03:17:0912255 std::unique_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5012256 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4112257 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3012258 EXPECT_EQ(ERR_IO_PENDING, rv);
12259 EXPECT_EQ(OK, callback_2.WaitForResult());
12260 const HttpResponseInfo* response = trans_2->GetResponseInfo();
wezca1070932016-05-26 20:30:5212261 ASSERT_TRUE(response);
12262 ASSERT_TRUE(response->auth_challenge);
[email protected]f45c1ee2010-08-03 00:54:3012263
12264 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4112265 TestCompletionCallback callback_3;
12266 rv = trans_2->RestartWithAuth(
12267 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3012268 EXPECT_EQ(ERR_IO_PENDING, rv);
12269 EXPECT_EQ(OK, callback_3.WaitForResult());
12270
12271 // After all that work, these two lines (or actually, just the scheme) are
12272 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3012273 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2312274 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3012275
[email protected]029c83b62013-01-24 05:28:2012276 LoadTimingInfo load_timing_info;
12277 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
12278 TestLoadTimingNotReusedWithPac(load_timing_info,
12279 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3812280}
12281
12282// Test that if we cancel the transaction as the connection is completing, that
12283// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0212284TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812285 // Setup everything about the connection to complete synchronously, so that
12286 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12287 // for is the callback from the HttpStreamRequest.
12288 // Then cancel the transaction.
12289 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612290 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812291 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612292 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12293 MockRead(SYNCHRONOUS, "hello world"),
12294 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812295 };
12296
[email protected]8e6441ca2010-08-19 05:56:3812297 HttpRequestInfo request;
12298 request.method = "GET";
bncce36dca22015-04-21 22:11:2312299 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812300 request.load_flags = 0;
12301
[email protected]bb88e1d32013-05-03 23:11:0712302 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912303 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12304 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112305 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2712306
[email protected]8e6441ca2010-08-19 05:56:3812307 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12308 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712309 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812310
[email protected]49639fa2011-12-20 23:22:4112311 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812312
vishal.b62985ca92015-04-17 08:45:5112313 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112314 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3812315 EXPECT_EQ(ERR_IO_PENDING, rv);
12316 trans.reset(); // Cancel the transaction here.
12317
fdoray92e35a72016-06-10 15:54:5512318 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012319}
12320
[email protected]ecab6e052014-05-16 14:58:1212321// Test that if a transaction is cancelled after receiving the headers, the
12322// stream is drained properly and added back to the socket pool. The main
12323// purpose of this test is to make sure that an HttpStreamParser can be read
12324// from after the HttpNetworkTransaction and the objects it owns have been
12325// deleted.
12326// See http://crbug.com/368418
12327TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
12328 MockRead data_reads[] = {
12329 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12330 MockRead(ASYNC, "Content-Length: 2\r\n"),
12331 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12332 MockRead(ASYNC, "1"),
12333 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12334 // HttpNetworkTransaction has been deleted.
12335 MockRead(ASYNC, "2"),
12336 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12337 };
12338 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12339 session_deps_.socket_factory->AddSocketDataProvider(&data);
12340
danakj1fd259a02016-04-16 03:17:0912341 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212342
12343 {
12344 HttpRequestInfo request;
12345 request.method = "GET";
bncce36dca22015-04-21 22:11:2312346 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212347 request.load_flags = 0;
12348
dcheng48459ac22014-08-26 00:46:4112349 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212350 TestCompletionCallback callback;
12351
12352 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
12353 EXPECT_EQ(ERR_IO_PENDING, rv);
12354 callback.WaitForResult();
12355
12356 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212357 ASSERT_TRUE(response);
12358 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212359 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12360
12361 // The transaction and HttpRequestInfo are deleted.
12362 }
12363
12364 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512365 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212366
12367 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112368 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212369}
12370
[email protected]76a505b2010-08-25 06:23:0012371// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0212372TEST_P(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312373 session_deps_.proxy_service =
12374 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112375 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712376 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912377 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012378
[email protected]76a505b2010-08-25 06:23:0012379 HttpRequestInfo request;
12380 request.method = "GET";
bncce36dca22015-04-21 22:11:2312381 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012382
12383 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312384 MockWrite(
12385 "GET http://www.example.org/ HTTP/1.1\r\n"
12386 "Host: www.example.org\r\n"
12387 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012388 };
12389
12390 MockRead data_reads1[] = {
12391 MockRead("HTTP/1.1 200 OK\r\n"),
12392 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12393 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612394 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012395 };
12396
12397 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12398 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712399 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012400
[email protected]49639fa2011-12-20 23:22:4112401 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012402
danakj1fd259a02016-04-16 03:17:0912403 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012404 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ryansturm49a8cb12016-06-15 16:51:0912405 BeforeHeadersSentHandler headers_handler;
12406 trans->SetBeforeHeadersSentCallback(
12407 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12408 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012409
[email protected]49639fa2011-12-20 23:22:4112410 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012411 EXPECT_EQ(ERR_IO_PENDING, rv);
12412
12413 rv = callback1.WaitForResult();
12414 EXPECT_EQ(OK, rv);
12415
12416 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212417 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012418
12419 EXPECT_TRUE(response->headers->IsKeepAlive());
12420 EXPECT_EQ(200, response->headers->response_code());
12421 EXPECT_EQ(100, response->headers->GetContentLength());
12422 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512423 EXPECT_TRUE(
12424 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
ryansturm49a8cb12016-06-15 16:51:0912425 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12426 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12427 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012428 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012429
12430 LoadTimingInfo load_timing_info;
12431 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12432 TestLoadTimingNotReusedWithPac(load_timing_info,
12433 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012434}
12435
12436// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0212437TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312438 session_deps_.proxy_service =
12439 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112440 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712441 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912442 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012443
[email protected]76a505b2010-08-25 06:23:0012444 HttpRequestInfo request;
12445 request.method = "GET";
bncce36dca22015-04-21 22:11:2312446 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012447
12448 // Since we have proxy, should try to establish tunnel.
12449 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712450 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12451 "Host: www.example.org:443\r\n"
12452 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012453
rsleevidb16bb02015-11-12 23:47:1712454 MockWrite("GET / HTTP/1.1\r\n"
12455 "Host: www.example.org\r\n"
12456 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012457 };
12458
12459 MockRead data_reads1[] = {
12460 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12461
12462 MockRead("HTTP/1.1 200 OK\r\n"),
12463 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12464 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612465 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012466 };
12467
12468 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12469 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712470 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612471 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712472 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012473
[email protected]49639fa2011-12-20 23:22:4112474 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012475
danakj1fd259a02016-04-16 03:17:0912476 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012477 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ryansturm49a8cb12016-06-15 16:51:0912478 BeforeHeadersSentHandler headers_handler;
12479 trans->SetBeforeHeadersSentCallback(
12480 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12481 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012482
[email protected]49639fa2011-12-20 23:22:4112483 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012484 EXPECT_EQ(ERR_IO_PENDING, rv);
12485
12486 rv = callback1.WaitForResult();
12487 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4612488 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012489 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012490 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012491 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012492 NetLog::PHASE_NONE);
12493 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012494 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012495 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12496 NetLog::PHASE_NONE);
12497
12498 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212499 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012500
12501 EXPECT_TRUE(response->headers->IsKeepAlive());
12502 EXPECT_EQ(200, response->headers->response_code());
12503 EXPECT_EQ(100, response->headers->GetContentLength());
12504 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12505 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512506 EXPECT_TRUE(
12507 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
ryansturm49a8cb12016-06-15 16:51:0912508 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12509 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12510 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012511
12512 LoadTimingInfo load_timing_info;
12513 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12514 TestLoadTimingNotReusedWithPac(load_timing_info,
12515 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012516}
12517
rsleevidb16bb02015-11-12 23:47:1712518// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12519// literal host.
12520TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
12521 session_deps_.proxy_service =
12522 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12523 BoundTestNetLog log;
12524 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912525 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712526
12527 HttpRequestInfo request;
12528 request.method = "GET";
12529 request.url = GURL("https://[::1]:443/");
12530
12531 // Since we have proxy, should try to establish tunnel.
12532 MockWrite data_writes1[] = {
12533 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12534 "Host: [::1]:443\r\n"
12535 "Proxy-Connection: keep-alive\r\n\r\n"),
12536
12537 MockWrite("GET / HTTP/1.1\r\n"
12538 "Host: [::1]\r\n"
12539 "Connection: keep-alive\r\n\r\n"),
12540 };
12541
12542 MockRead data_reads1[] = {
12543 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12544
12545 MockRead("HTTP/1.1 200 OK\r\n"),
12546 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12547 MockRead("Content-Length: 100\r\n\r\n"),
12548 MockRead(SYNCHRONOUS, OK),
12549 };
12550
12551 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12552 data_writes1, arraysize(data_writes1));
12553 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12554 SSLSocketDataProvider ssl(ASYNC, OK);
12555 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12556
12557 TestCompletionCallback callback1;
12558
danakj1fd259a02016-04-16 03:17:0912559 std::unique_ptr<HttpTransaction> trans(
rsleevidb16bb02015-11-12 23:47:1712560 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12561
12562 int rv = trans->Start(&request, callback1.callback(), log.bound());
12563 EXPECT_EQ(ERR_IO_PENDING, rv);
12564
12565 rv = callback1.WaitForResult();
12566 EXPECT_EQ(OK, rv);
12567 TestNetLogEntry::List entries;
12568 log.GetEntries(&entries);
12569 size_t pos = ExpectLogContainsSomewhere(
12570 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12571 NetLog::PHASE_NONE);
12572 ExpectLogContainsSomewhere(
12573 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12574 NetLog::PHASE_NONE);
12575
12576 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212577 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712578
12579 EXPECT_TRUE(response->headers->IsKeepAlive());
12580 EXPECT_EQ(200, response->headers->response_code());
12581 EXPECT_EQ(100, response->headers->GetContentLength());
12582 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12583 EXPECT_TRUE(response->was_fetched_via_proxy);
12584 EXPECT_TRUE(
12585 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
12586
12587 LoadTimingInfo load_timing_info;
12588 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12589 TestLoadTimingNotReusedWithPac(load_timing_info,
12590 CONNECT_TIMING_HAS_SSL_TIMES);
12591}
12592
[email protected]76a505b2010-08-25 06:23:0012593// Test a basic HTTPS GET request through a proxy, but the server hangs up
12594// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0212595TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312596 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112597 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712598 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912599 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012600
[email protected]76a505b2010-08-25 06:23:0012601 HttpRequestInfo request;
12602 request.method = "GET";
bncce36dca22015-04-21 22:11:2312603 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012604
12605 // Since we have proxy, should try to establish tunnel.
12606 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712607 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12608 "Host: www.example.org:443\r\n"
12609 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012610
rsleevidb16bb02015-11-12 23:47:1712611 MockWrite("GET / HTTP/1.1\r\n"
12612 "Host: www.example.org\r\n"
12613 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012614 };
12615
12616 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0612617 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0012618 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612619 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0012620 };
12621
12622 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12623 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712624 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612625 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012627
[email protected]49639fa2011-12-20 23:22:4112628 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012629
danakj1fd259a02016-04-16 03:17:0912630 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012631 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5012632
[email protected]49639fa2011-12-20 23:22:4112633 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012634 EXPECT_EQ(ERR_IO_PENDING, rv);
12635
12636 rv = callback1.WaitForResult();
12637 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4612638 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012639 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012640 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012641 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012642 NetLog::PHASE_NONE);
12643 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012644 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012645 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12646 NetLog::PHASE_NONE);
12647}
12648
[email protected]749eefa82010-09-13 22:14:0312649// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0212650TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
danakj1fd259a02016-04-16 03:17:0912651 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912652 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1312653 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0312654
danakj1fd259a02016-04-16 03:17:0912655 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5512656 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912657 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5512658 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0312659 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312660 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0312661 };
12662
rch8e6c6c42015-05-01 14:05:1312663 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12664 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712665 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0312666
[email protected]8ddf8322012-02-23 18:08:0612667 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812668 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712669 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0312670
danakj1fd259a02016-04-16 03:17:0912671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0312672
12673 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2312674 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012675 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312676 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712677 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4212678 CreateInsecureSpdySession(session.get(), key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312679
12680 HttpRequestInfo request;
12681 request.method = "GET";
bncce36dca22015-04-21 22:11:2312682 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0312683 request.load_flags = 0;
12684
12685 // This is the important line that marks this as a preconnect.
12686 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
12687
danakj1fd259a02016-04-16 03:17:0912688 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012689 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0312690
[email protected]41d64e82013-07-03 22:44:2612691 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4112692 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312693 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112694 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0312695}
12696
[email protected]73b8dd222010-11-11 19:55:2412697// Given a net error, cause that error to be returned from the first Write()
12698// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0212699void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0712700 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2912701 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712702 request_info.url = GURL("https://www.example.com/");
12703 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912704 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712705
[email protected]8ddf8322012-02-23 18:08:0612706 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2912707 MockWrite data_writes[] = {
12708 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2412709 };
ttuttle859dc7a2015-04-23 19:42:2912710 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712711 session_deps_.socket_factory->AddSocketDataProvider(&data);
12712 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2412713
danakj1fd259a02016-04-16 03:17:0912714 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12715 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012716 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2412717
[email protected]49639fa2011-12-20 23:22:4112718 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912719 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12720 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2412721 rv = callback.WaitForResult();
12722 ASSERT_EQ(error, rv);
12723}
12724
[email protected]23e482282013-06-14 16:08:0212725TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2412726 // Just check a grab bag of cert errors.
12727 static const int kErrors[] = {
12728 ERR_CERT_COMMON_NAME_INVALID,
12729 ERR_CERT_AUTHORITY_INVALID,
12730 ERR_CERT_DATE_INVALID,
12731 };
12732 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0612733 CheckErrorIsPassedBack(kErrors[i], ASYNC);
12734 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2412735 }
12736}
12737
[email protected]bd0b6772011-01-11 19:59:3012738// Ensure that a client certificate is removed from the SSL client auth
12739// cache when:
12740// 1) No proxy is involved.
12741// 2) TLS False Start is disabled.
12742// 3) The initial TLS handshake requests a client certificate.
12743// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212744TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312745 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912746 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712747 request_info.url = GURL("https://www.example.com/");
12748 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912749 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712750
[email protected]bd0b6772011-01-11 19:59:3012751 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112752 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012753
12754 // [ssl_]data1 contains the data for the first SSL handshake. When a
12755 // CertificateRequest is received for the first time, the handshake will
12756 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2912757 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012758 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912760 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712761 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012762
12763 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
12764 // False Start is not being used, the result of the SSL handshake will be
12765 // returned as part of the SSLClientSocket::Connect() call. This test
12766 // matches the result of a server sending a handshake_failure alert,
12767 // rather than a Finished message, because it requires a client
12768 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2912769 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012770 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712771 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912772 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712773 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012774
12775 // [ssl_]data3 contains the data for the third SSL handshake. When a
12776 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212777 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
12778 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3012779 // of the HttpNetworkTransaction. Because this test failure is due to
12780 // requiring a client certificate, this fallback handshake should also
12781 // fail.
ttuttle859dc7a2015-04-23 19:42:2912782 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012783 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712784 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912785 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712786 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012787
[email protected]80c75f682012-05-26 16:22:1712788 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
12789 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212790 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
12791 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1712792 // of the HttpNetworkTransaction. Because this test failure is due to
12793 // requiring a client certificate, this fallback handshake should also
12794 // fail.
ttuttle859dc7a2015-04-23 19:42:2912795 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1712796 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712797 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912798 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712799 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712800
danakj1fd259a02016-04-16 03:17:0912801 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12802 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012803 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012804
[email protected]bd0b6772011-01-11 19:59:3012805 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4112806 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912807 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12808 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012809
12810 // Complete the SSL handshake, which should abort due to requiring a
12811 // client certificate.
12812 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912813 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012814
12815 // Indicate that no certificate should be supplied. From the perspective
12816 // of SSLClientCertCache, NULL is just as meaningful as a real
12817 // certificate, so this is the same as supply a
12818 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412819 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912820 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012821
12822 // Ensure the certificate was added to the client auth cache before
12823 // allowing the connection to continue restarting.
12824 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412825 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112826 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412827 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212828 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012829
12830 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712831 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12832 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012833 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912834 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012835
12836 // Ensure that the client certificate is removed from the cache on a
12837 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112838 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412839 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012840}
12841
12842// Ensure that a client certificate is removed from the SSL client auth
12843// cache when:
12844// 1) No proxy is involved.
12845// 2) TLS False Start is enabled.
12846// 3) The initial TLS handshake requests a client certificate.
12847// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212848TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312849 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912850 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712851 request_info.url = GURL("https://www.example.com/");
12852 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912853 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712854
[email protected]bd0b6772011-01-11 19:59:3012855 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112856 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012857
12858 // When TLS False Start is used, SSLClientSocket::Connect() calls will
12859 // return successfully after reading up to the peer's Certificate message.
12860 // This is to allow the caller to call SSLClientSocket::Write(), which can
12861 // enqueue application data to be sent in the same packet as the
12862 // ChangeCipherSpec and Finished messages.
12863 // The actual handshake will be finished when SSLClientSocket::Read() is
12864 // called, which expects to process the peer's ChangeCipherSpec and
12865 // Finished messages. If there was an error negotiating with the peer,
12866 // such as due to the peer requiring a client certificate when none was
12867 // supplied, the alert sent by the peer won't be processed until Read() is
12868 // called.
12869
12870 // Like the non-False Start case, when a client certificate is requested by
12871 // the peer, the handshake is aborted during the Connect() call.
12872 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2912873 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012874 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912876 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712877 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012878
12879 // When a client certificate is supplied, Connect() will not be aborted
12880 // when the peer requests the certificate. Instead, the handshake will
12881 // artificially succeed, allowing the caller to write the HTTP request to
12882 // the socket. The handshake messages are not processed until Read() is
12883 // called, which then detects that the handshake was aborted, due to the
12884 // peer sending a handshake_failure because it requires a client
12885 // certificate.
ttuttle859dc7a2015-04-23 19:42:2912886 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012887 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712888 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912889 MockRead data2_reads[] = {
12890 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3012891 };
ttuttle859dc7a2015-04-23 19:42:2912892 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712893 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012894
12895 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1712896 // the data for the SSL handshake once the TLSv1.1 connection falls back to
12897 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912898 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012899 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712900 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912901 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712902 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012903
[email protected]80c75f682012-05-26 16:22:1712904 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
12905 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912906 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1712907 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712908 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912909 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712910 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712911
[email protected]7799de12013-05-30 05:52:5112912 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2912913 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5112914 ssl_data5.cert_request_info = cert_request.get();
12915 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2912916 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5112917 session_deps_.socket_factory->AddSocketDataProvider(&data5);
12918
danakj1fd259a02016-04-16 03:17:0912919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12920 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012921 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012922
[email protected]bd0b6772011-01-11 19:59:3012923 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4112924 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912925 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12926 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012927
12928 // Complete the SSL handshake, which should abort due to requiring a
12929 // client certificate.
12930 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912931 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012932
12933 // Indicate that no certificate should be supplied. From the perspective
12934 // of SSLClientCertCache, NULL is just as meaningful as a real
12935 // certificate, so this is the same as supply a
12936 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412937 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912938 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012939
12940 // Ensure the certificate was added to the client auth cache before
12941 // allowing the connection to continue restarting.
12942 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412943 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112944 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412945 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212946 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012947
[email protected]bd0b6772011-01-11 19:59:3012948 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712949 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12950 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012951 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912952 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012953
12954 // Ensure that the client certificate is removed from the cache on a
12955 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112956 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412957 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012958}
12959
[email protected]8c405132011-01-11 22:03:1812960// Ensure that a client certificate is removed from the SSL client auth
12961// cache when:
12962// 1) An HTTPS proxy is involved.
12963// 3) The HTTPS proxy requests a client certificate.
12964// 4) The client supplies an invalid/unacceptable certificate for the
12965// proxy.
12966// The test is repeated twice, first for connecting to an HTTPS endpoint,
12967// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0212968TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0312969 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5112970 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712971 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1812972
12973 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112974 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1812975
12976 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
12977 // [ssl_]data[1-3]. Rather than represending the endpoint
12978 // (www.example.com:443), they represent failures with the HTTPS proxy
12979 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2912980 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1812981 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712982 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912983 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712984 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1812985
ttuttle859dc7a2015-04-23 19:42:2912986 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812987 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712988 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912989 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712990 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1812991
[email protected]80c75f682012-05-26 16:22:1712992 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
12993#if 0
ttuttle859dc7a2015-04-23 19:42:2912994 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812995 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712996 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912997 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712998 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1712999#endif
[email protected]8c405132011-01-11 22:03:1813000
ttuttle859dc7a2015-04-23 19:42:2913001 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1813002 requests[0].url = GURL("https://www.example.com/");
13003 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913004 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813005
13006 requests[1].url = GURL("http://www.example.com/");
13007 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913008 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813009
13010 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713011 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913012 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13013 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013014 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1813015
13016 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113017 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2913018 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
13019 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1813020
13021 // Complete the SSL handshake, which should abort due to requiring a
13022 // client certificate.
13023 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2913024 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1813025
13026 // Indicate that no certificate should be supplied. From the perspective
13027 // of SSLClientCertCache, NULL is just as meaningful as a real
13028 // certificate, so this is the same as supply a
13029 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5413030 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2913031 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1813032
13033 // Ensure the certificate was added to the client auth cache before
13034 // allowing the connection to continue restarting.
13035 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413036 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113037 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413038 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213039 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813040 // Ensure the certificate was NOT cached for the endpoint. This only
13041 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113042 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413043 HostPortPair("www.example.com", 443), &client_cert,
13044 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813045
13046 // Restart the handshake. This will consume ssl_data2, which fails, and
13047 // then consume ssl_data3, which should also fail. The result code is
13048 // checked against what ssl_data3 should return.
13049 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2913050 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1813051
13052 // Now that the new handshake has failed, ensure that the client
13053 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113054 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413055 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113056 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413057 HostPortPair("www.example.com", 443), &client_cert,
13058 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813059 }
13060}
13061
mmenke5c642132015-06-02 16:05:1313062TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bncf33fb31b2016-01-29 15:22:2613063 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4613064
13065 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713066 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2613068 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
13069 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4613070
[email protected]8ddf8322012-02-23 18:08:0613071 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813072 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713073 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4613074
danakj1fd259a02016-04-16 03:17:0913075 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913076 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813077 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0913078 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913079 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613080 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313081 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613082 };
danakj1fd259a02016-04-16 03:17:0913083 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213084 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913085 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213086 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913087 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0213088 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913089 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0213090 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613091 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1313092 CreateMockRead(*host1_resp, 1),
13093 CreateMockRead(*host1_resp_body, 2),
13094 CreateMockRead(*host2_resp, 4),
13095 CreateMockRead(*host2_resp_body, 5),
13096 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613097 };
13098
eroman36d84e54432016-03-17 03:23:0213099 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213100 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313101 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13102 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713103 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613104
[email protected]aa22b242011-11-16 18:58:2913105 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613106 HttpRequestInfo request1;
13107 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313108 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613109 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013110 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613111
[email protected]49639fa2011-12-20 23:22:4113112 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613113 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113114 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613115
13116 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213117 ASSERT_TRUE(response);
13118 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213119 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613120
13121 std::string response_data;
13122 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
13123 EXPECT_EQ("hello!", response_data);
13124
13125 // Preload www.gmail.com into HostCache.
13126 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1013127 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613128 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1013129 rv = session_deps_.host_resolver->Resolve(resolve_info,
13130 DEFAULT_PRIORITY,
13131 &ignored,
13132 callback.callback(),
13133 NULL,
13134 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4713135 EXPECT_EQ(ERR_IO_PENDING, rv);
13136 rv = callback.WaitForResult();
13137 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4613138
13139 HttpRequestInfo request2;
13140 request2.method = "GET";
13141 request2.url = GURL("https://www.gmail.com/");
13142 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013143 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613144
[email protected]49639fa2011-12-20 23:22:4113145 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613146 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113147 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613148
13149 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213150 ASSERT_TRUE(response);
13151 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213152 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613153 EXPECT_TRUE(response->was_fetched_via_spdy);
13154 EXPECT_TRUE(response->was_npn_negotiated);
13155 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
13156 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613157}
13158
[email protected]23e482282013-06-14 16:08:0213159TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bncf33fb31b2016-01-29 15:22:2613160 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d2b5f092012-06-08 23:55:0213161
13162 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713163 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913164 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213165 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
13166 pool_peer.DisableDomainAuthenticationVerification();
13167
13168 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813169 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713170 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0213171
danakj1fd259a02016-04-16 03:17:0913172 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913173 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813174 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0913175 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913176 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213177 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313178 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213179 };
danakj1fd259a02016-04-16 03:17:0913180 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213181 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913182 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213183 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913184 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0213185 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913186 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0213187 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213188 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1313189 CreateMockRead(*host1_resp, 1),
13190 CreateMockRead(*host1_resp_body, 2),
13191 CreateMockRead(*host2_resp, 4),
13192 CreateMockRead(*host2_resp_body, 5),
13193 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213194 };
13195
eroman36d84e54432016-03-17 03:23:0213196 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213197 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313198 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13199 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713200 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213201
13202 TestCompletionCallback callback;
13203 HttpRequestInfo request1;
13204 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313205 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213206 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013207 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213208
13209 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
13210 EXPECT_EQ(ERR_IO_PENDING, rv);
13211 EXPECT_EQ(OK, callback.WaitForResult());
13212
13213 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213214 ASSERT_TRUE(response);
13215 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213216 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213217
13218 std::string response_data;
13219 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
13220 EXPECT_EQ("hello!", response_data);
13221
13222 HttpRequestInfo request2;
13223 request2.method = "GET";
13224 request2.url = GURL("https://www.gmail.com/");
13225 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013226 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213227
13228 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
13229 EXPECT_EQ(ERR_IO_PENDING, rv);
13230 EXPECT_EQ(OK, callback.WaitForResult());
13231
13232 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213233 ASSERT_TRUE(response);
13234 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213235 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213236 EXPECT_TRUE(response->was_fetched_via_spdy);
13237 EXPECT_TRUE(response->was_npn_negotiated);
13238 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
13239 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213240}
13241
ttuttle859dc7a2015-04-23 19:42:2913242class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4613243 public:
13244 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
13245 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013246 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613247
13248 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
13249
13250 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2013251 int Resolve(const RequestInfo& info,
13252 RequestPriority priority,
13253 AddressList* addresses,
13254 const CompletionCallback& callback,
13255 RequestHandle* out_req,
13256 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013257 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1013258 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4013259 }
13260
dchengb03027d2014-10-21 12:00:2013261 int ResolveFromCache(const RequestInfo& info,
13262 AddressList* addresses,
13263 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013264 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
13265 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0913266 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613267 return rv;
13268 }
13269
dchengb03027d2014-10-21 12:00:2013270 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4613271 host_resolver_.CancelRequest(req);
13272 }
13273
[email protected]46da33be2011-07-19 21:58:0413274 MockCachingHostResolver* GetMockHostResolver() {
13275 return &host_resolver_;
13276 }
13277
[email protected]e3ceb682011-06-28 23:55:4613278 private:
13279 MockCachingHostResolver host_resolver_;
13280 const HostPortPair host_port_;
13281};
13282
mmenke5c642132015-06-02 16:05:1313283TEST_P(HttpNetworkTransactionTest,
13284 UseIPConnectionPoolingWithHostCacheExpiration) {
bncf33fb31b2016-01-29 15:22:2613285 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4613286
13287 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4613288 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3413289 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0713290 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4613291 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0913292 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2613293 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
13294 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4613295
[email protected]8ddf8322012-02-23 18:08:0613296 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813297 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713298 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4613299
danakj1fd259a02016-04-16 03:17:0913300 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913301 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813302 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0913303 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913304 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613305 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313306 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613307 };
danakj1fd259a02016-04-16 03:17:0913308 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213309 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913310 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213311 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913312 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0213313 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913314 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0213315 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613316 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1313317 CreateMockRead(*host1_resp, 1),
13318 CreateMockRead(*host1_resp_body, 2),
13319 CreateMockRead(*host2_resp, 4),
13320 CreateMockRead(*host2_resp_body, 5),
13321 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613322 };
13323
eroman36d84e54432016-03-17 03:23:0213324 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213325 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313326 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13327 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713328 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613329
[email protected]aa22b242011-11-16 18:58:2913330 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613331 HttpRequestInfo request1;
13332 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313333 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613334 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013335 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613336
[email protected]49639fa2011-12-20 23:22:4113337 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613338 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113339 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613340
13341 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213342 ASSERT_TRUE(response);
13343 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213344 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613345
13346 std::string response_data;
13347 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
13348 EXPECT_EQ("hello!", response_data);
13349
13350 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1013351 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613352 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1013353 rv = host_resolver.Resolve(resolve_info,
13354 DEFAULT_PRIORITY,
13355 &ignored,
13356 callback.callback(),
13357 NULL,
13358 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4713359 EXPECT_EQ(ERR_IO_PENDING, rv);
13360 rv = callback.WaitForResult();
13361 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4613362
13363 HttpRequestInfo request2;
13364 request2.method = "GET";
13365 request2.url = GURL("https://www.gmail.com/");
13366 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013367 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613368
[email protected]49639fa2011-12-20 23:22:4113369 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613370 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113371 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613372
13373 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213374 ASSERT_TRUE(response);
13375 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213376 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613377 EXPECT_TRUE(response->was_fetched_via_spdy);
13378 EXPECT_TRUE(response->was_npn_negotiated);
13379 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
13380 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613381}
13382
[email protected]23e482282013-06-14 16:08:0213383TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313384 const std::string https_url = "https://www.example.org:8080/";
13385 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413386
13387 // SPDY GET for HTTPS URL
danakj1fd259a02016-04-16 03:17:0913388 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913389 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413390
13391 MockWrite writes1[] = {
13392 CreateMockWrite(*req1, 0),
13393 };
13394
danakj1fd259a02016-04-16 03:17:0913395 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5513396 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913397 std::unique_ptr<SpdySerializedFrame> body1(
bncb03b1092016-04-06 11:19:5513398 spdy_util_.ConstructSpdyBodyFrame(1, true));
mmenkee24011922015-12-17 22:12:5913399 MockRead reads1[] = {CreateMockRead(*resp1, 1), CreateMockRead(*body1, 2),
13400 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413401
rch8e6c6c42015-05-01 14:05:1313402 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13403 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413404 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713405 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413406
13407 // HTTP GET for the HTTP URL
13408 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313409 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413410 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313411 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413412 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413413 };
13414
13415 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313416 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13417 MockRead(ASYNC, 2, "hello"),
13418 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413419 };
13420
rch8e6c6c42015-05-01 14:05:1313421 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13422 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413423
[email protected]8450d722012-07-02 19:14:0413424 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813425 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713426 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13427 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13428 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413429
danakj1fd259a02016-04-16 03:17:0913430 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413431
13432 // Start the first transaction to set up the SpdySession
13433 HttpRequestInfo request1;
13434 request1.method = "GET";
13435 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413436 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013437 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413438 TestCompletionCallback callback1;
13439 EXPECT_EQ(ERR_IO_PENDING,
13440 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5513441 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413442
13443 EXPECT_EQ(OK, callback1.WaitForResult());
13444 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13445
13446 // Now, start the HTTP request
13447 HttpRequestInfo request2;
13448 request2.method = "GET";
13449 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413450 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013451 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413452 TestCompletionCallback callback2;
13453 EXPECT_EQ(ERR_IO_PENDING,
13454 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5513455 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413456
13457 EXPECT_EQ(OK, callback2.WaitForResult());
13458 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13459}
13460
bnc1b0e36852015-04-28 15:32:5913461class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
13462 public:
13463 void Run(bool pooling, bool valid) {
zhongyi3d4a55e72016-04-22 20:36:4613464 url::SchemeHostPort server(GURL(valid ? "https://mail.example.org:443"
13465 : "https://invalid.example.org:443"));
bnc1b0e36852015-04-28 15:32:5913466 HostPortPair alternative("www.example.org", 443);
13467
13468 base::FilePath certs_dir = GetTestCertsDirectory();
13469 scoped_refptr<X509Certificate> cert(
13470 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
wezca1070932016-05-26 20:30:5213471 ASSERT_TRUE(cert);
bnc1b0e36852015-04-28 15:32:5913472 bool common_name_fallback_used;
13473 EXPECT_EQ(valid,
zhongyi3d4a55e72016-04-22 20:36:4613474 cert->VerifyNameMatch(server.host(), &common_name_fallback_used));
bnc1b0e36852015-04-28 15:32:5913475 EXPECT_TRUE(
13476 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
13477 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813478 ssl.SetNextProto(GetProtocol());
bnc1b0e36852015-04-28 15:32:5913479 ssl.cert = cert;
13480 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13481
13482 // If pooling, then start a request to alternative first to create a
13483 // SpdySession.
13484 std::string url0 = "https://www.example.org:443";
zhongyi3d4a55e72016-04-22 20:36:4613485 // Second request to server, which has an alternative service, and could
bnc1b0e36852015-04-28 15:32:5913486 // open a connection to the alternative host or pool to the existing one.
13487 std::string url1("https://");
zhongyi3d4a55e72016-04-22 20:36:4613488 url1.append(server.host());
bnc1b0e36852015-04-28 15:32:5913489 url1.append(":443");
13490
danakj1fd259a02016-04-16 03:17:0913491 std::unique_ptr<SpdySerializedFrame> req0;
13492 std::unique_ptr<SpdySerializedFrame> req1;
13493 std::unique_ptr<SpdySerializedFrame> resp0;
13494 std::unique_ptr<SpdySerializedFrame> body0;
13495 std::unique_ptr<SpdySerializedFrame> resp1;
13496 std::unique_ptr<SpdySerializedFrame> body1;
bnc1b0e36852015-04-28 15:32:5913497 std::vector<MockWrite> writes;
13498 std::vector<MockRead> reads;
13499
13500 if (pooling) {
bnc38dcd392016-02-09 23:19:4913501 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813502 spdy_util_.UpdateWithStreamDestruction(1);
bnc38dcd392016-02-09 23:19:4913503 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 3, LOWEST));
bnc1b0e36852015-04-28 15:32:5913504
13505 writes.push_back(CreateMockWrite(*req0, 0));
13506 writes.push_back(CreateMockWrite(*req1, 3));
13507
13508 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13509 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13510 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
13511 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
13512
13513 reads.push_back(CreateMockRead(*resp0, 1));
13514 reads.push_back(CreateMockRead(*body0, 2));
13515 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
13516 reads.push_back(CreateMockRead(*resp1, 5));
13517 reads.push_back(CreateMockRead(*body1, 6));
13518 reads.push_back(MockRead(ASYNC, OK, 7));
13519 } else {
bnc38dcd392016-02-09 23:19:4913520 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 1, LOWEST));
bnc1b0e36852015-04-28 15:32:5913521
13522 writes.push_back(CreateMockWrite(*req1, 0));
13523
13524 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13525 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13526
13527 reads.push_back(CreateMockRead(*resp1, 1));
13528 reads.push_back(CreateMockRead(*body1, 2));
13529 reads.push_back(MockRead(ASYNC, OK, 3));
13530 }
13531
davidben5f8b6bc2015-11-25 03:19:5413532 SequencedSocketData data(reads.data(), reads.size(), writes.data(),
13533 writes.size());
bnc1b0e36852015-04-28 15:32:5913534 session_deps_.socket_factory->AddSocketDataProvider(&data);
13535
zhongyi3d4a55e72016-04-22 20:36:4613536 // Connection to the server fails.
bnc1b0e36852015-04-28 15:32:5913537 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13538 StaticSocketDataProvider data_refused;
13539 data_refused.set_connect_data(mock_connect);
13540 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13541
bncf33fb31b2016-01-29 15:22:2613542 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913543 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc1b0e36852015-04-28 15:32:5913544 base::WeakPtr<HttpServerProperties> http_server_properties =
13545 session->http_server_properties();
13546 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813547 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213548 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613549 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013550 expiration);
bnc1b0e36852015-04-28 15:32:5913551
13552 // First request to alternative.
13553 if (pooling) {
danakj1fd259a02016-04-16 03:17:0913554 std::unique_ptr<HttpTransaction> trans0(
bnc1b0e36852015-04-28 15:32:5913555 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13556 HttpRequestInfo request0;
13557 request0.method = "GET";
13558 request0.url = GURL(url0);
13559 request0.load_flags = 0;
13560 TestCompletionCallback callback0;
13561
13562 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
13563 EXPECT_EQ(ERR_IO_PENDING, rv);
13564 rv = callback0.WaitForResult();
13565 EXPECT_EQ(OK, rv);
13566 }
13567
13568 // Second request to origin.
danakj1fd259a02016-04-16 03:17:0913569 std::unique_ptr<HttpTransaction> trans1(
bnc1b0e36852015-04-28 15:32:5913570 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13571 HttpRequestInfo request1;
13572 request1.method = "GET";
13573 request1.url = GURL(url1);
13574 request1.load_flags = 0;
13575 TestCompletionCallback callback1;
13576
13577 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13578 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:5513579 base::RunLoop().RunUntilIdle();
mmenkee24011922015-12-17 22:12:5913580 if (data.IsPaused())
13581 data.Resume();
bnc1b0e36852015-04-28 15:32:5913582 rv = callback1.WaitForResult();
13583 if (valid) {
13584 EXPECT_EQ(OK, rv);
13585 } else {
13586 if (pooling) {
13587 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13588 } else {
13589 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
13590 }
13591 }
13592 }
13593};
13594
rdsmithebb50aa2015-11-12 03:44:3813595INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc1b0e36852015-04-28 15:32:5913596 AltSvcCertificateVerificationTest,
rdsmithebb50aa2015-11-12 03:44:3813597 testing::Values(kTestCaseSPDY31,
13598 kTestCaseHTTP2NoPriorityDependencies,
13599 kTestCaseHTTP2PriorityDependencies));
bnc1b0e36852015-04-28 15:32:5913600
13601// The alternative service host must exhibit a certificate that is valid for the
13602// origin host. Test that this is enforced when pooling to an existing
13603// connection.
13604TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
13605 Run(true, true);
13606}
13607
13608TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
13609 Run(true, false);
13610}
13611
13612// The alternative service host must exhibit a certificate that is valid for the
13613// origin host. Test that this is enforced when opening a new connection.
13614TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
13615 Run(false, true);
13616}
13617
bnc8bef8da22016-05-30 01:28:2513618// TODO(bnc): Re-enable when https://crbug.com/615413 is fixed.
13619TEST_P(AltSvcCertificateVerificationTest, DISABLED_NewConnectionInvalid) {
bnc1b0e36852015-04-28 15:32:5913620 Run(false, false);
13621}
13622
bnc5452e2a2015-05-08 16:27:4213623// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13624// with the alternative server. That connection should not be used.
13625TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2513626 url::SchemeHostPort server("https", "www.example.org", 443);
13627 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4213628
bnc8bef8da22016-05-30 01:28:2513629 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4213630 SSLSocketDataProvider ssl(ASYNC, OK);
13631 ssl.SetNextProto(kProtoHTTP11);
13632 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13633
13634 // No data should be read from the alternative, because HTTP/1.1 is
13635 // negotiated.
13636 StaticSocketDataProvider data;
13637 session_deps_.socket_factory->AddSocketDataProvider(&data);
13638
13639 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4613640 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4213641 // mocked. This way the request relies on the alternate Job.
13642 StaticSocketDataProvider data_refused;
13643 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13644 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13645
zhongyi3d4a55e72016-04-22 20:36:4613646 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613647 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913648 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213649 base::WeakPtr<HttpServerProperties> http_server_properties =
13650 session->http_server_properties();
13651 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813652 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213653 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613654 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013655 expiration);
bnc5452e2a2015-05-08 16:27:4213656
danakj1fd259a02016-04-16 03:17:0913657 std::unique_ptr<HttpTransaction> trans(
bnc5452e2a2015-05-08 16:27:4213658 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13659 HttpRequestInfo request;
13660 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2513661 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4213662 request.load_flags = 0;
13663 TestCompletionCallback callback;
13664
13665 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
13666 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
13667 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13668 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
13669}
13670
bnc40448a532015-05-11 19:13:1413671// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4613672// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1413673// succeeds, the request should succeed, even if the latter fails because
13674// HTTP/1.1 is negotiated which is insufficient for alternative service.
13675TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2513676 url::SchemeHostPort server("https", "www.example.org", 443);
13677 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1413678
13679 // Negotiate HTTP/1.1 with alternative.
13680 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
13681 alternative_ssl.SetNextProto(kProtoHTTP11);
13682 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13683
13684 // No data should be read from the alternative, because HTTP/1.1 is
13685 // negotiated.
13686 StaticSocketDataProvider data;
13687 session_deps_.socket_factory->AddSocketDataProvider(&data);
13688
zhongyi3d4a55e72016-04-22 20:36:4613689 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1413690 SSLSocketDataProvider origin_ssl(ASYNC, OK);
13691 origin_ssl.SetNextProto(kProtoHTTP11);
13692 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13693
13694 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2513695 MockWrite("GET / HTTP/1.1\r\n"
13696 "Host: www.example.org\r\n"
13697 "Connection: keep-alive\r\n\r\n"),
13698 MockWrite("GET /second HTTP/1.1\r\n"
13699 "Host: www.example.org\r\n"
13700 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1413701 };
13702
13703 MockRead http_reads[] = {
13704 MockRead("HTTP/1.1 200 OK\r\n"),
13705 MockRead("Content-Type: text/html\r\n"),
13706 MockRead("Content-Length: 6\r\n\r\n"),
13707 MockRead("foobar"),
13708 MockRead("HTTP/1.1 200 OK\r\n"),
13709 MockRead("Content-Type: text/html\r\n"),
13710 MockRead("Content-Length: 7\r\n\r\n"),
13711 MockRead("another"),
13712 };
13713 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13714 http_writes, arraysize(http_writes));
13715 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13716
zhongyi3d4a55e72016-04-22 20:36:4613717 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613718 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913719 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc40448a532015-05-11 19:13:1413720 base::WeakPtr<HttpServerProperties> http_server_properties =
13721 session->http_server_properties();
13722 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813723 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213724 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613725 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013726 expiration);
bnc40448a532015-05-11 19:13:1413727
13728 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13729 HttpRequestInfo request1;
13730 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2513731 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1413732 request1.load_flags = 0;
13733 TestCompletionCallback callback1;
13734
13735 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
13736 rv = callback1.GetResult(rv);
13737 EXPECT_EQ(OK, rv);
13738
13739 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213740 ASSERT_TRUE(response1);
13741 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1413742 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13743
13744 std::string response_data1;
13745 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
13746 EXPECT_EQ("foobar", response_data1);
13747
13748 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13749 // for alternative service.
13750 EXPECT_TRUE(
13751 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13752
zhongyi3d4a55e72016-04-22 20:36:4613753 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1413754 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4613755 // to server.
bnc40448a532015-05-11 19:13:1413756 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13757 HttpRequestInfo request2;
13758 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2513759 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1413760 request2.load_flags = 0;
13761 TestCompletionCallback callback2;
13762
13763 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
13764 rv = callback2.GetResult(rv);
13765 EXPECT_EQ(OK, rv);
13766
13767 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213768 ASSERT_TRUE(response2);
13769 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1413770 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13771
13772 std::string response_data2;
13773 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
13774 EXPECT_EQ("another", response_data2);
13775}
13776
bnc5452e2a2015-05-08 16:27:4213777// Alternative service requires HTTP/2 (or SPDY), but there is already a
13778// HTTP/1.1 socket open to the alternative server. That socket should not be
13779// used.
13780TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4613781 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4213782 HostPortPair alternative("alternative.example.org", 443);
13783 std::string origin_url = "https://origin.example.org:443";
13784 std::string alternative_url = "https://alternative.example.org:443";
13785
13786 // Negotiate HTTP/1.1 with alternative.example.org.
13787 SSLSocketDataProvider ssl(ASYNC, OK);
13788 ssl.SetNextProto(kProtoHTTP11);
13789 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13790
13791 // HTTP/1.1 data for |request1| and |request2|.
13792 MockWrite http_writes[] = {
13793 MockWrite(
13794 "GET / HTTP/1.1\r\n"
13795 "Host: alternative.example.org\r\n"
13796 "Connection: keep-alive\r\n\r\n"),
13797 MockWrite(
13798 "GET / HTTP/1.1\r\n"
13799 "Host: alternative.example.org\r\n"
13800 "Connection: keep-alive\r\n\r\n"),
13801 };
13802
13803 MockRead http_reads[] = {
13804 MockRead(
13805 "HTTP/1.1 200 OK\r\n"
13806 "Content-Type: text/html; charset=iso-8859-1\r\n"
13807 "Content-Length: 40\r\n\r\n"
13808 "first HTTP/1.1 response from alternative"),
13809 MockRead(
13810 "HTTP/1.1 200 OK\r\n"
13811 "Content-Type: text/html; charset=iso-8859-1\r\n"
13812 "Content-Length: 41\r\n\r\n"
13813 "second HTTP/1.1 response from alternative"),
13814 };
13815 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13816 http_writes, arraysize(http_writes));
13817 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13818
13819 // This test documents that an alternate Job should not pool to an already
13820 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4613821 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4213822 StaticSocketDataProvider data_refused;
13823 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13824 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13825
zhongyi3d4a55e72016-04-22 20:36:4613826 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613827 session_deps_.enable_alternative_service_with_different_host = false;
danakj1fd259a02016-04-16 03:17:0913828 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213829 base::WeakPtr<HttpServerProperties> http_server_properties =
13830 session->http_server_properties();
13831 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813832 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213833 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613834 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013835 expiration);
bnc5452e2a2015-05-08 16:27:4213836
13837 // First transaction to alternative to open an HTTP/1.1 socket.
danakj1fd259a02016-04-16 03:17:0913838 std::unique_ptr<HttpTransaction> trans1(
bnc5452e2a2015-05-08 16:27:4213839 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13840 HttpRequestInfo request1;
13841 request1.method = "GET";
13842 request1.url = GURL(alternative_url);
13843 request1.load_flags = 0;
13844 TestCompletionCallback callback1;
13845
13846 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13847 EXPECT_EQ(OK, callback1.GetResult(rv));
13848 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13849 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5213850 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4213851 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13852 EXPECT_TRUE(response1->was_npn_negotiated);
13853 EXPECT_FALSE(response1->was_fetched_via_spdy);
13854 std::string response_data1;
13855 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
13856 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
13857
13858 // Request for origin.example.org, which has an alternative service. This
13859 // will start two Jobs: the alternative looks for connections to pool to,
13860 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4613861 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4213862 // this request fails.
danakj1fd259a02016-04-16 03:17:0913863 std::unique_ptr<HttpTransaction> trans2(
bnc5452e2a2015-05-08 16:27:4213864 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13865 HttpRequestInfo request2;
13866 request2.method = "GET";
13867 request2.url = GURL(origin_url);
13868 request2.load_flags = 0;
13869 TestCompletionCallback callback2;
13870
13871 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
13872 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
13873
13874 // Another transaction to alternative. This is to test that the HTTP/1.1
13875 // socket is still open and in the pool.
danakj1fd259a02016-04-16 03:17:0913876 std::unique_ptr<HttpTransaction> trans3(
bnc5452e2a2015-05-08 16:27:4213877 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13878 HttpRequestInfo request3;
13879 request3.method = "GET";
13880 request3.url = GURL(alternative_url);
13881 request3.load_flags = 0;
13882 TestCompletionCallback callback3;
13883
13884 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
13885 EXPECT_EQ(OK, callback3.GetResult(rv));
13886 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
13887 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5213888 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4213889 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
13890 EXPECT_TRUE(response3->was_npn_negotiated);
13891 EXPECT_FALSE(response3->was_fetched_via_spdy);
13892 std::string response_data3;
13893 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
13894 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
13895}
13896
[email protected]23e482282013-06-14 16:08:0213897TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2313898 const std::string https_url = "https://www.example.org:8080/";
13899 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413900
rdsmithebb50aa2015-11-12 03:44:3813901 // Separate SPDY util instance for naked and wrapped requests.
13902 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
13903
[email protected]8450d722012-07-02 19:14:0413904 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2313905 const HostPortPair host_port_pair("www.example.org", 8080);
danakj1fd259a02016-04-16 03:17:0913906 std::unique_ptr<SpdySerializedFrame> connect(
lgarrona91df87f2014-12-05 00:51:3413907 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
danakj1fd259a02016-04-16 03:17:0913908 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913909 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
danakj1fd259a02016-04-16 03:17:0913910 std::unique_ptr<SpdySerializedFrame> wrapped_req1(
[email protected]23e482282013-06-14 16:08:0213911 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3913912
13913 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2913914 SpdyHeaderBlock req2_block;
bnc7ecc1122015-09-28 13:22:4913915 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]745aa9c2014-06-27 02:21:2913916 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2313917 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2913918 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4913919 req2_block[spdy_util_.GetPathKey()] = "/";
danakj1fd259a02016-04-16 03:17:0913920 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913921 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0413922
13923 MockWrite writes1[] = {
mmenke666a6fea2015-12-19 04:16:3313924 CreateMockWrite(*connect, 0), CreateMockWrite(*wrapped_req1, 2),
13925 CreateMockWrite(*req2, 6),
[email protected]8450d722012-07-02 19:14:0413926 };
13927
danakj1fd259a02016-04-16 03:17:0913928 std::unique_ptr<SpdySerializedFrame> conn_resp(
bnc38dcd392016-02-09 23:19:4913929 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0913930 std::unique_ptr<SpdySerializedFrame> resp1(
bnc38dcd392016-02-09 23:19:4913931 spdy_util_wrapped.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0913932 std::unique_ptr<SpdySerializedFrame> body1(
bnc38dcd392016-02-09 23:19:4913933 spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913934 std::unique_ptr<SpdySerializedFrame> wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3813935 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
danakj1fd259a02016-04-16 03:17:0913936 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3813937 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
danakj1fd259a02016-04-16 03:17:0913938 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5513939 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913940 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5513941 spdy_util_.ConstructSpdyBodyFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3313942 MockRead reads1[] = {
13943 CreateMockRead(*conn_resp, 1),
13944 MockRead(ASYNC, ERR_IO_PENDING, 3),
13945 CreateMockRead(*wrapped_resp1, 4),
13946 CreateMockRead(*wrapped_body1, 5),
13947 MockRead(ASYNC, ERR_IO_PENDING, 7),
13948 CreateMockRead(*resp2, 8),
13949 CreateMockRead(*body2, 9),
13950 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
13951 };
[email protected]8450d722012-07-02 19:14:0413952
mmenke666a6fea2015-12-19 04:16:3313953 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13954 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413955 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713956 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413957
rdsmith82957ad2015-09-16 19:42:0313958 session_deps_.proxy_service =
13959 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5113960 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713961 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0413962 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3813963 ssl1.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313964 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0413965 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3813966 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313967 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13968 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0413969
danakj1fd259a02016-04-16 03:17:0913970 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0413971
13972 // Start the first transaction to set up the SpdySession
13973 HttpRequestInfo request1;
13974 request1.method = "GET";
13975 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413976 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013977 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413978 TestCompletionCallback callback1;
mmenke666a6fea2015-12-19 04:16:3313979 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0413980
mmenke666a6fea2015-12-19 04:16:3313981 // This pause is a hack to avoid running into https://crbug.com/497228.
13982 data1.RunUntilPaused();
13983 base::RunLoop().RunUntilIdle();
13984 data1.Resume();
13985 EXPECT_EQ(OK, callback1.GetResult(rv));
[email protected]8450d722012-07-02 19:14:0413986 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13987
[email protected]f6c63db52013-02-02 00:35:2213988 LoadTimingInfo load_timing_info1;
13989 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
13990 TestLoadTimingNotReusedWithPac(load_timing_info1,
13991 CONNECT_TIMING_HAS_SSL_TIMES);
13992
mmenke666a6fea2015-12-19 04:16:3313993 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0413994 HttpRequestInfo request2;
13995 request2.method = "GET";
13996 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413997 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013998 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413999 TestCompletionCallback callback2;
mmenke666a6fea2015-12-19 04:16:3314000 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0414001
mmenke666a6fea2015-12-19 04:16:3314002 // This pause is a hack to avoid running into https://crbug.com/497228.
14003 data1.RunUntilPaused();
14004 base::RunLoop().RunUntilIdle();
14005 data1.Resume();
14006 EXPECT_EQ(OK, callback2.GetResult(rv));
14007
[email protected]8450d722012-07-02 19:14:0414008 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214009
14010 LoadTimingInfo load_timing_info2;
14011 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14012 // The established SPDY sessions is considered reused by the HTTP request.
14013 TestLoadTimingReusedWithPac(load_timing_info2);
14014 // HTTP requests over a SPDY session should have a different connection
14015 // socket_log_id than requests over a tunnel.
14016 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414017}
14018
[email protected]2d88e7d2012-07-19 17:55:1714019// Test that in the case where we have a SPDY session to a SPDY proxy
14020// that we do not pool other origins that resolve to the same IP when
14021// the certificate does not match the new origin.
14022// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0214023TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314024 const std::string url1 = "http://www.example.org/";
14025 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714026 const std::string ip_addr = "1.2.3.4";
14027
rdsmithebb50aa2015-11-12 03:44:3814028 // Second SpdyTestUtil instance for the second socket.
14029 SpdyTestUtil spdy_util_secure(GetProtocol(), GetDependenciesFromPriority());
14030
[email protected]2d88e7d2012-07-19 17:55:1714031 // SPDY GET for HTTP URL (through SPDY proxy)
danakj1fd259a02016-04-16 03:17:0914032 std::unique_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2314033 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
danakj1fd259a02016-04-16 03:17:0914034 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4914035 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714036
14037 MockWrite writes1[] = {
14038 CreateMockWrite(*req1, 0),
14039 };
14040
danakj1fd259a02016-04-16 03:17:0914041 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5514042 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914043 std::unique_ptr<SpdySerializedFrame> body1(
bncb03b1092016-04-06 11:19:5514044 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714045 MockRead reads1[] = {
mmenke666a6fea2015-12-19 04:16:3314046 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*resp1, 2),
14047 CreateMockRead(*body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714048 };
14049
mmenke666a6fea2015-12-19 04:16:3314050 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14051 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214052 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914053 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714054 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14055 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314056 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714057
14058 // SPDY GET for HTTPS URL (direct)
danakj1fd259a02016-04-16 03:17:0914059 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4914060 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714061
14062 MockWrite writes2[] = {
14063 CreateMockWrite(*req2, 0),
14064 };
14065
danakj1fd259a02016-04-16 03:17:0914066 std::unique_ptr<SpdySerializedFrame> resp2(
rdsmithebb50aa2015-11-12 03:44:3814067 spdy_util_secure.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914068 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5514069 spdy_util_secure.ConstructSpdyBodyFrame(1, true));
mmenke666a6fea2015-12-19 04:16:3314070 MockRead reads2[] = {CreateMockRead(*resp2, 1), CreateMockRead(*body2, 2),
14071 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714072
mmenke666a6fea2015-12-19 04:16:3314073 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14074 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714075 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314076 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714077
14078 // Set up a proxy config that sends HTTP requests to a proxy, and
14079 // all others direct.
14080 ProxyConfig proxy_config;
14081 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0714082 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0914083 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0414084 NULL));
[email protected]2d88e7d2012-07-19 17:55:1714085
bncce36dca22015-04-21 22:11:2314086 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3814087 ssl1.SetNextProto(GetProtocol());
[email protected]2d88e7d2012-07-19 17:55:1714088 // Load a valid cert. Note, that this does not need to
14089 // be valid for proxy because the MockSSLClientSocket does
14090 // not actually verify it. But SpdySession will use this
14091 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314092 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214093 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314094 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14095 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714096
14097 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3814098 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3314099 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14100 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714101
[email protected]bb88e1d32013-05-03 23:11:0714102 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2314103 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714104 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714105
danakj1fd259a02016-04-16 03:17:0914106 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714107
14108 // Start the first transaction to set up the SpdySession
14109 HttpRequestInfo request1;
14110 request1.method = "GET";
14111 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714112 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014113 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714114 TestCompletionCallback callback1;
14115 ASSERT_EQ(ERR_IO_PENDING,
14116 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
mmenke666a6fea2015-12-19 04:16:3314117 // This pause is a hack to avoid running into https://crbug.com/497228.
14118 data1.RunUntilPaused();
14119 base::RunLoop().RunUntilIdle();
14120 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714121
[email protected]2d88e7d2012-07-19 17:55:1714122 EXPECT_EQ(OK, callback1.WaitForResult());
14123 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14124
14125 // Now, start the HTTP request
14126 HttpRequestInfo request2;
14127 request2.method = "GET";
14128 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714129 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014130 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714131 TestCompletionCallback callback2;
14132 EXPECT_EQ(ERR_IO_PENDING,
14133 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5514134 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714135
14136 ASSERT_TRUE(callback2.have_result());
14137 EXPECT_EQ(OK, callback2.WaitForResult());
14138 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14139}
14140
[email protected]85f97342013-04-17 06:12:2414141// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14142// error) in SPDY session, removes the socket from pool and closes the SPDY
14143// session. Verify that new url's from the same HttpNetworkSession (and a new
14144// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0214145TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314146 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414147
14148 MockRead reads1[] = {
14149 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14150 };
14151
mmenke11eb5152015-06-09 14:50:5014152 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414153
danakj1fd259a02016-04-16 03:17:0914154 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4914155 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414156 MockWrite writes2[] = {
14157 CreateMockWrite(*req2, 0),
14158 };
14159
danakj1fd259a02016-04-16 03:17:0914160 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5514161 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914162 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5514163 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414164 MockRead reads2[] = {
14165 CreateMockRead(*resp2, 1),
14166 CreateMockRead(*body2, 2),
14167 MockRead(ASYNC, OK, 3) // EOF
14168 };
14169
mmenke11eb5152015-06-09 14:50:5014170 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14171 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414172
[email protected]85f97342013-04-17 06:12:2414173 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814174 ssl1.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5014175 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14176 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414177
14178 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814179 ssl2.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5014180 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14181 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414182
danakj1fd259a02016-04-16 03:17:0914183 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014184 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414185
14186 // Start the first transaction to set up the SpdySession and verify that
14187 // connection was closed.
14188 HttpRequestInfo request1;
14189 request1.method = "GET";
14190 request1.url = GURL(https_url);
14191 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014192 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414193 TestCompletionCallback callback1;
14194 EXPECT_EQ(ERR_IO_PENDING,
14195 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2414196 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
14197
14198 // Now, start the second request and make sure it succeeds.
14199 HttpRequestInfo request2;
14200 request2.method = "GET";
14201 request2.url = GURL(https_url);
14202 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014203 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414204 TestCompletionCallback callback2;
14205 EXPECT_EQ(ERR_IO_PENDING,
14206 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2414207
mmenke11eb5152015-06-09 14:50:5014208 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2414209 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14210}
14211
[email protected]23e482282013-06-14 16:08:0214212TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314213 ClientSocketPoolManager::set_max_sockets_per_group(
14214 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14215 ClientSocketPoolManager::set_max_sockets_per_pool(
14216 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14217
14218 // Use two different hosts with different IPs so they don't get pooled.
14219 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14220 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914221 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314222
14223 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814224 ssl1.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0314225 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814226 ssl2.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0314227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14228 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14229
danakj1fd259a02016-04-16 03:17:0914230 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4914231 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314232 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1314233 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314234 };
danakj1fd259a02016-04-16 03:17:0914235 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0214236 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914237 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0214238 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314239 MockRead spdy1_reads[] = {
mmenkee24011922015-12-17 22:12:5914240 CreateMockRead(*host1_resp, 1), CreateMockRead(*host1_resp_body, 2),
14241 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314242 };
14243
rdsmithebb50aa2015-11-12 03:44:3814244 // Use a separate test instance for the separate SpdySession that will be
14245 // created.
14246 SpdyTestUtil spdy_util_2(GetProtocol(), GetDependenciesFromPriority());
danakj1fd259a02016-04-16 03:17:0914247 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1314248 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14249 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0314250 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14251
danakj1fd259a02016-04-16 03:17:0914252 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4914253 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314254 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1314255 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314256 };
danakj1fd259a02016-04-16 03:17:0914257 std::unique_ptr<SpdySerializedFrame> host2_resp(
rdsmithebb50aa2015-11-12 03:44:3814258 spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914259 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
rdsmithebb50aa2015-11-12 03:44:3814260 spdy_util_2.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314261 MockRead spdy2_reads[] = {
mmenkee24011922015-12-17 22:12:5914262 CreateMockRead(*host2_resp, 1), CreateMockRead(*host2_resp_body, 2),
14263 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314264 };
14265
danakj1fd259a02016-04-16 03:17:0914266 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1314267 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14268 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0314269 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14270
14271 MockWrite http_write[] = {
14272 MockWrite("GET / HTTP/1.1\r\n"
14273 "Host: www.a.com\r\n"
14274 "Connection: keep-alive\r\n\r\n"),
14275 };
14276
14277 MockRead http_read[] = {
14278 MockRead("HTTP/1.1 200 OK\r\n"),
14279 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14280 MockRead("Content-Length: 6\r\n\r\n"),
14281 MockRead("hello!"),
14282 };
14283 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14284 http_write, arraysize(http_write));
14285 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14286
14287 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014288 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314289 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314290 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614291 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314292
14293 TestCompletionCallback callback;
14294 HttpRequestInfo request1;
14295 request1.method = "GET";
14296 request1.url = GURL("https://www.a.com/");
14297 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0914298 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5014299 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314300
14301 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
14302 EXPECT_EQ(ERR_IO_PENDING, rv);
14303 EXPECT_EQ(OK, callback.WaitForResult());
14304
14305 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214306 ASSERT_TRUE(response);
14307 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214308 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314309 EXPECT_TRUE(response->was_fetched_via_spdy);
14310 EXPECT_TRUE(response->was_npn_negotiated);
14311
14312 std::string response_data;
14313 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14314 EXPECT_EQ("hello!", response_data);
14315 trans.reset();
14316 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614317 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314318
14319 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014320 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314321 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314322 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614323 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314324 HttpRequestInfo request2;
14325 request2.method = "GET";
14326 request2.url = GURL("https://www.b.com/");
14327 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014328 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314329
14330 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
14331 EXPECT_EQ(ERR_IO_PENDING, rv);
14332 EXPECT_EQ(OK, callback.WaitForResult());
14333
14334 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214335 ASSERT_TRUE(response);
14336 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214337 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314338 EXPECT_TRUE(response->was_fetched_via_spdy);
14339 EXPECT_TRUE(response->was_npn_negotiated);
14340 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14341 EXPECT_EQ("hello!", response_data);
14342 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614343 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314344 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614345 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314346
14347 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014348 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314349 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314350 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614351 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314352 HttpRequestInfo request3;
14353 request3.method = "GET";
14354 request3.url = GURL("http://www.a.com/");
14355 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014356 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314357
14358 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
14359 EXPECT_EQ(ERR_IO_PENDING, rv);
14360 EXPECT_EQ(OK, callback.WaitForResult());
14361
14362 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214363 ASSERT_TRUE(response);
14364 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314365 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14366 EXPECT_FALSE(response->was_fetched_via_spdy);
14367 EXPECT_FALSE(response->was_npn_negotiated);
14368 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14369 EXPECT_EQ("hello!", response_data);
14370 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614371 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314372 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614373 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314374}
14375
[email protected]79e1fd62013-06-20 06:50:0414376TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
14377 HttpRequestInfo request;
14378 request.method = "GET";
bncce36dca22015-04-21 22:11:2314379 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414380 request.load_flags = 0;
14381
danakj1fd259a02016-04-16 03:17:0914382 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14383 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114384 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414385
ttuttled9dbc652015-09-29 20:00:5914386 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414387 StaticSocketDataProvider data;
14388 data.set_connect_data(mock_connect);
14389 session_deps_.socket_factory->AddSocketDataProvider(&data);
14390
14391 TestCompletionCallback callback;
14392
14393 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14394 EXPECT_EQ(ERR_IO_PENDING, rv);
14395
14396 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5914397 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0414398
[email protected]79e1fd62013-06-20 06:50:0414399 // We don't care whether this succeeds or fails, but it shouldn't crash.
14400 HttpRequestHeaders request_headers;
14401 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714402
14403 ConnectionAttempts attempts;
14404 trans->GetConnectionAttempts(&attempts);
14405 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5914406 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
14407
14408 IPEndPoint endpoint;
14409 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
14410 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414411}
14412
14413TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
14414 HttpRequestInfo request;
14415 request.method = "GET";
bncce36dca22015-04-21 22:11:2314416 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414417 request.load_flags = 0;
14418
danakj1fd259a02016-04-16 03:17:0914419 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14420 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114421 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414422
ttuttled9dbc652015-09-29 20:00:5914423 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414424 StaticSocketDataProvider data;
14425 data.set_connect_data(mock_connect);
14426 session_deps_.socket_factory->AddSocketDataProvider(&data);
14427
14428 TestCompletionCallback callback;
14429
14430 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14431 EXPECT_EQ(ERR_IO_PENDING, rv);
14432
14433 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5914434 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0414435
[email protected]79e1fd62013-06-20 06:50:0414436 // We don't care whether this succeeds or fails, but it shouldn't crash.
14437 HttpRequestHeaders request_headers;
14438 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714439
14440 ConnectionAttempts attempts;
14441 trans->GetConnectionAttempts(&attempts);
14442 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5914443 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
14444
14445 IPEndPoint endpoint;
14446 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
14447 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414448}
14449
14450TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
14451 HttpRequestInfo request;
14452 request.method = "GET";
bncce36dca22015-04-21 22:11:2314453 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414454 request.load_flags = 0;
14455
danakj1fd259a02016-04-16 03:17:0914456 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14457 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114458 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414459
14460 MockWrite data_writes[] = {
14461 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14462 };
14463 MockRead data_reads[] = {
14464 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14465 };
14466
14467 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14468 data_writes, arraysize(data_writes));
14469 session_deps_.socket_factory->AddSocketDataProvider(&data);
14470
14471 TestCompletionCallback callback;
14472
14473 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14474 EXPECT_EQ(ERR_IO_PENDING, rv);
14475
14476 rv = callback.WaitForResult();
14477 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14478
[email protected]79e1fd62013-06-20 06:50:0414479 HttpRequestHeaders request_headers;
14480 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14481 EXPECT_TRUE(request_headers.HasHeader("Host"));
14482}
14483
14484TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
14485 HttpRequestInfo request;
14486 request.method = "GET";
bncce36dca22015-04-21 22:11:2314487 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414488 request.load_flags = 0;
14489
danakj1fd259a02016-04-16 03:17:0914490 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14491 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114492 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414493
14494 MockWrite data_writes[] = {
14495 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14496 };
14497 MockRead data_reads[] = {
14498 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14499 };
14500
14501 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14502 data_writes, arraysize(data_writes));
14503 session_deps_.socket_factory->AddSocketDataProvider(&data);
14504
14505 TestCompletionCallback callback;
14506
14507 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14508 EXPECT_EQ(ERR_IO_PENDING, rv);
14509
14510 rv = callback.WaitForResult();
14511 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14512
[email protected]79e1fd62013-06-20 06:50:0414513 HttpRequestHeaders request_headers;
14514 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14515 EXPECT_TRUE(request_headers.HasHeader("Host"));
14516}
14517
14518TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
14519 HttpRequestInfo request;
14520 request.method = "GET";
bncce36dca22015-04-21 22:11:2314521 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414522 request.load_flags = 0;
14523
danakj1fd259a02016-04-16 03:17:0914524 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14525 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114526 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414527
14528 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314529 MockWrite(
14530 "GET / HTTP/1.1\r\n"
14531 "Host: www.example.org\r\n"
14532 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414533 };
14534 MockRead data_reads[] = {
14535 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14536 };
14537
14538 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14539 data_writes, arraysize(data_writes));
14540 session_deps_.socket_factory->AddSocketDataProvider(&data);
14541
14542 TestCompletionCallback callback;
14543
14544 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14545 EXPECT_EQ(ERR_IO_PENDING, rv);
14546
14547 rv = callback.WaitForResult();
14548 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14549
[email protected]79e1fd62013-06-20 06:50:0414550 HttpRequestHeaders request_headers;
14551 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14552 EXPECT_TRUE(request_headers.HasHeader("Host"));
14553}
14554
14555TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
14556 HttpRequestInfo request;
14557 request.method = "GET";
bncce36dca22015-04-21 22:11:2314558 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414559 request.load_flags = 0;
14560
danakj1fd259a02016-04-16 03:17:0914561 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14562 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114563 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414564
14565 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314566 MockWrite(
14567 "GET / HTTP/1.1\r\n"
14568 "Host: www.example.org\r\n"
14569 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414570 };
14571 MockRead data_reads[] = {
14572 MockRead(ASYNC, ERR_CONNECTION_RESET),
14573 };
14574
14575 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14576 data_writes, arraysize(data_writes));
14577 session_deps_.socket_factory->AddSocketDataProvider(&data);
14578
14579 TestCompletionCallback callback;
14580
14581 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14582 EXPECT_EQ(ERR_IO_PENDING, rv);
14583
14584 rv = callback.WaitForResult();
14585 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14586
[email protected]79e1fd62013-06-20 06:50:0414587 HttpRequestHeaders request_headers;
14588 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14589 EXPECT_TRUE(request_headers.HasHeader("Host"));
14590}
14591
14592TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
14593 HttpRequestInfo request;
14594 request.method = "GET";
bncce36dca22015-04-21 22:11:2314595 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414596 request.load_flags = 0;
14597 request.extra_headers.SetHeader("X-Foo", "bar");
14598
danakj1fd259a02016-04-16 03:17:0914599 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14600 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114601 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414602
14603 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314604 MockWrite(
14605 "GET / HTTP/1.1\r\n"
14606 "Host: www.example.org\r\n"
14607 "Connection: keep-alive\r\n"
14608 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414609 };
14610 MockRead data_reads[] = {
14611 MockRead("HTTP/1.1 200 OK\r\n"
14612 "Content-Length: 5\r\n\r\n"
14613 "hello"),
14614 MockRead(ASYNC, ERR_UNEXPECTED),
14615 };
14616
14617 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14618 data_writes, arraysize(data_writes));
14619 session_deps_.socket_factory->AddSocketDataProvider(&data);
14620
14621 TestCompletionCallback callback;
14622
14623 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14624 EXPECT_EQ(ERR_IO_PENDING, rv);
14625
14626 rv = callback.WaitForResult();
14627 EXPECT_EQ(OK, rv);
14628
14629 HttpRequestHeaders request_headers;
14630 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14631 std::string foo;
14632 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14633 EXPECT_EQ("bar", foo);
14634}
14635
[email protected]bf828982013-08-14 18:01:4714636namespace {
14637
yhiranoa7e05bb2014-11-06 05:40:3914638// Fake HttpStream that simply records calls to SetPriority().
14639class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314640 public base::SupportsWeakPtr<FakeStream> {
14641 public:
14642 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014643 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314644
14645 RequestPriority priority() const { return priority_; }
14646
dchengb03027d2014-10-21 12:00:2014647 int InitializeStream(const HttpRequestInfo* request_info,
14648 RequestPriority priority,
14649 const BoundNetLog& net_log,
14650 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314651 return ERR_IO_PENDING;
14652 }
14653
dchengb03027d2014-10-21 12:00:2014654 int SendRequest(const HttpRequestHeaders& request_headers,
14655 HttpResponseInfo* response,
14656 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314657 ADD_FAILURE();
14658 return ERR_UNEXPECTED;
14659 }
14660
dchengb03027d2014-10-21 12:00:2014661 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314662 ADD_FAILURE();
14663 return ERR_UNEXPECTED;
14664 }
14665
dchengb03027d2014-10-21 12:00:2014666 int ReadResponseBody(IOBuffer* buf,
14667 int buf_len,
14668 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314669 ADD_FAILURE();
14670 return ERR_UNEXPECTED;
14671 }
14672
dchengb03027d2014-10-21 12:00:2014673 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314674
dchengb03027d2014-10-21 12:00:2014675 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314676 ADD_FAILURE();
14677 return false;
14678 }
14679
dchengb03027d2014-10-21 12:00:2014680 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314681 ADD_FAILURE();
14682 return false;
14683 }
14684
dchengb03027d2014-10-21 12:00:2014685 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314686
mmenkebd84c392015-09-02 14:12:3414687 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314688
sclittle4de1bab92015-09-22 21:28:2414689 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914690 ADD_FAILURE();
14691 return 0;
14692 }
14693
sclittlebe1ccf62015-09-02 19:40:3614694 int64_t GetTotalSentBytes() const override {
14695 ADD_FAILURE();
14696 return 0;
14697 }
14698
dchengb03027d2014-10-21 12:00:2014699 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314700 ADD_FAILURE();
14701 return false;
14702 }
14703
dchengb03027d2014-10-21 12:00:2014704 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14705
14706 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314707 ADD_FAILURE();
14708 }
14709
ttuttled9dbc652015-09-29 20:00:5914710 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14711
nharperb7441ef2016-01-25 23:54:1414712 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14713 std::vector<uint8_t>* out) override {
14714 ADD_FAILURE();
14715 return ERR_NOT_IMPLEMENTED;
14716 }
14717
dchengb03027d2014-10-21 12:00:2014718 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314719
zhongyica364fbb2015-12-12 03:39:1214720 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14721
dchengb03027d2014-10-21 12:00:2014722 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314723
yhiranoa7e05bb2014-11-06 05:40:3914724 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
14725
14726 HttpStream* RenewStreamForAuth() override { return NULL; }
14727
[email protected]e86839fd2013-08-14 18:29:0314728 private:
14729 RequestPriority priority_;
14730
14731 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14732};
14733
14734// Fake HttpStreamRequest that simply records calls to SetPriority()
14735// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714736class FakeStreamRequest : public HttpStreamRequest,
14737 public base::SupportsWeakPtr<FakeStreamRequest> {
14738 public:
[email protected]e86839fd2013-08-14 18:29:0314739 FakeStreamRequest(RequestPriority priority,
14740 HttpStreamRequest::Delegate* delegate)
14741 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414742 delegate_(delegate),
14743 websocket_stream_create_helper_(NULL) {}
14744
14745 FakeStreamRequest(RequestPriority priority,
14746 HttpStreamRequest::Delegate* delegate,
14747 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14748 : priority_(priority),
14749 delegate_(delegate),
14750 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314751
dchengb03027d2014-10-21 12:00:2014752 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714753
14754 RequestPriority priority() const { return priority_; }
14755
[email protected]831e4a32013-11-14 02:14:4414756 const WebSocketHandshakeStreamBase::CreateHelper*
14757 websocket_stream_create_helper() const {
14758 return websocket_stream_create_helper_;
14759 }
14760
[email protected]e86839fd2013-08-14 18:29:0314761 // Create a new FakeStream and pass it to the request's
14762 // delegate. Returns a weak pointer to the FakeStream.
14763 base::WeakPtr<FakeStream> FinishStreamRequest() {
14764 FakeStream* fake_stream = new FakeStream(priority_);
14765 // Do this before calling OnStreamReady() as OnStreamReady() may
14766 // immediately delete |fake_stream|.
14767 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14768 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14769 return weak_stream;
14770 }
14771
dchengb03027d2014-10-21 12:00:2014772 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714773 ADD_FAILURE();
14774 return ERR_UNEXPECTED;
14775 }
14776
dchengb03027d2014-10-21 12:00:2014777 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714778 ADD_FAILURE();
14779 return LoadState();
14780 }
14781
dchengb03027d2014-10-21 12:00:2014782 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714783
dchengb03027d2014-10-21 12:00:2014784 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714785
dchengb03027d2014-10-21 12:00:2014786 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714787
dchengb03027d2014-10-21 12:00:2014788 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714789
ttuttle1f2d7e92015-04-28 16:17:4714790 const ConnectionAttempts& connection_attempts() const override {
14791 static ConnectionAttempts no_attempts;
14792 return no_attempts;
14793 }
14794
[email protected]bf828982013-08-14 18:01:4714795 private:
14796 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314797 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414798 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714799
14800 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14801};
14802
14803// Fake HttpStreamFactory that vends FakeStreamRequests.
14804class FakeStreamFactory : public HttpStreamFactory {
14805 public:
14806 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014807 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714808
14809 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14810 // RequestStream() (which may be NULL if it was destroyed already).
14811 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14812 return last_stream_request_;
14813 }
14814
dchengb03027d2014-10-21 12:00:2014815 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14816 RequestPriority priority,
14817 const SSLConfig& server_ssl_config,
14818 const SSLConfig& proxy_ssl_config,
14819 HttpStreamRequest::Delegate* delegate,
14820 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314821 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714822 last_stream_request_ = fake_request->AsWeakPtr();
14823 return fake_request;
14824 }
14825
xunjieli5749218c2016-03-22 16:43:0614826 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0814827 const HttpRequestInfo& info,
14828 RequestPriority priority,
14829 const SSLConfig& server_ssl_config,
14830 const SSLConfig& proxy_ssl_config,
14831 HttpStreamRequest::Delegate* delegate,
14832 const BoundNetLog& net_log) override {
14833 NOTREACHED();
14834 return nullptr;
14835 }
14836
dchengb03027d2014-10-21 12:00:2014837 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714838 const HttpRequestInfo& info,
14839 RequestPriority priority,
14840 const SSLConfig& server_ssl_config,
14841 const SSLConfig& proxy_ssl_config,
14842 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614843 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1314844 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414845 FakeStreamRequest* fake_request =
14846 new FakeStreamRequest(priority, delegate, create_helper);
14847 last_stream_request_ = fake_request->AsWeakPtr();
14848 return fake_request;
[email protected]bf828982013-08-14 18:01:4714849 }
14850
dchengb03027d2014-10-21 12:00:2014851 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5914852 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4714853 ADD_FAILURE();
14854 }
14855
dchengb03027d2014-10-21 12:00:2014856 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714857 ADD_FAILURE();
14858 return NULL;
14859 }
14860
14861 private:
14862 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14863
14864 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14865};
14866
Adam Rice425cf122015-01-19 06:18:2414867// TODO(ricea): Maybe unify this with the one in
14868// url_request_http_job_unittest.cc ?
14869class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14870 public:
danakj1fd259a02016-04-16 03:17:0914871 FakeWebSocketBasicHandshakeStream(
14872 std::unique_ptr<ClientSocketHandle> connection,
14873 bool using_proxy)
Adam Rice425cf122015-01-19 06:18:2414874 : state_(connection.release(), using_proxy) {}
14875
14876 // Fake implementation of HttpStreamBase methods.
14877 // This ends up being quite "real" because this object has to really send data
14878 // on the mock socket. It might be easier to use the real implementation, but
14879 // the fact that the WebSocket code is not compiled on iOS makes that
14880 // difficult.
14881 int InitializeStream(const HttpRequestInfo* request_info,
14882 RequestPriority priority,
14883 const BoundNetLog& net_log,
14884 const CompletionCallback& callback) override {
14885 state_.Initialize(request_info, priority, net_log, callback);
14886 return OK;
14887 }
14888
14889 int SendRequest(const HttpRequestHeaders& request_headers,
14890 HttpResponseInfo* response,
14891 const CompletionCallback& callback) override {
14892 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
14893 response, callback);
14894 }
14895
14896 int ReadResponseHeaders(const CompletionCallback& callback) override {
14897 return parser()->ReadResponseHeaders(callback);
14898 }
14899
14900 int ReadResponseBody(IOBuffer* buf,
14901 int buf_len,
14902 const CompletionCallback& callback) override {
14903 NOTREACHED();
14904 return ERR_IO_PENDING;
14905 }
14906
14907 void Close(bool not_reusable) override {
14908 if (parser())
14909 parser()->Close(true);
14910 }
14911
14912 bool IsResponseBodyComplete() const override {
14913 NOTREACHED();
14914 return false;
14915 }
14916
Adam Rice425cf122015-01-19 06:18:2414917 bool IsConnectionReused() const override {
14918 NOTREACHED();
14919 return false;
14920 }
14921 void SetConnectionReused() override { NOTREACHED(); }
14922
mmenkebd84c392015-09-02 14:12:3414923 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2414924
sclittle4de1bab92015-09-22 21:28:2414925 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2414926 NOTREACHED();
14927 return 0;
14928 }
14929
sclittlebe1ccf62015-09-02 19:40:3614930 int64_t GetTotalSentBytes() const override {
14931 NOTREACHED();
14932 return 0;
14933 }
14934
Adam Rice425cf122015-01-19 06:18:2414935 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
14936 NOTREACHED();
14937 return false;
14938 }
14939
Adam Ricecb76ac62015-02-20 05:33:2514940 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2414941
14942 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
14943 NOTREACHED();
14944 }
14945
ttuttled9dbc652015-09-29 20:00:5914946 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14947
nharperb7441ef2016-01-25 23:54:1414948 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14949 std::vector<uint8_t>* out) override {
14950 ADD_FAILURE();
14951 return ERR_NOT_IMPLEMENTED;
14952 }
14953
Adam Rice425cf122015-01-19 06:18:2414954 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
14955
zhongyica364fbb2015-12-12 03:39:1214956 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14957
Adam Rice425cf122015-01-19 06:18:2414958 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
14959
14960 UploadProgress GetUploadProgress() const override {
14961 NOTREACHED();
14962 return UploadProgress();
14963 }
14964
14965 HttpStream* RenewStreamForAuth() override {
14966 NOTREACHED();
14967 return nullptr;
14968 }
14969
14970 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0914971 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2414972 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0914973 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2414974 }
14975
14976 private:
14977 HttpStreamParser* parser() const { return state_.parser(); }
14978 HttpBasicState state_;
14979
14980 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
14981};
14982
[email protected]831e4a32013-11-14 02:14:4414983// TODO(yhirano): Split this class out into a net/websockets file, if it is
14984// worth doing.
14985class FakeWebSocketStreamCreateHelper :
14986 public WebSocketHandshakeStreamBase::CreateHelper {
14987 public:
dchengb03027d2014-10-21 12:00:2014988 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0914989 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1314990 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4814991 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2414992 using_proxy);
[email protected]831e4a32013-11-14 02:14:4414993 }
14994
dchengb03027d2014-10-21 12:00:2014995 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4414996 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1314997 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4414998 NOTREACHED();
14999 return NULL;
15000 };
15001
dchengb03027d2014-10-21 12:00:2015002 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4415003
danakj1fd259a02016-04-16 03:17:0915004 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4415005 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915006 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415007 }
15008};
15009
[email protected]bf828982013-08-14 18:01:4715010} // namespace
15011
15012// Make sure that HttpNetworkTransaction passes on its priority to its
15013// stream request on start.
15014TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915015 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215016 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715017 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915018 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715019
dcheng48459ac22014-08-26 00:46:4115020 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715021
wezca1070932016-05-26 20:30:5215022 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715023
15024 HttpRequestInfo request;
15025 TestCompletionCallback callback;
15026 EXPECT_EQ(ERR_IO_PENDING,
15027 trans.Start(&request, callback.callback(), BoundNetLog()));
15028
15029 base::WeakPtr<FakeStreamRequest> fake_request =
15030 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215031 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715032 EXPECT_EQ(LOW, fake_request->priority());
15033}
15034
15035// Make sure that HttpNetworkTransaction passes on its priority
15036// updates to its stream request.
15037TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915038 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215039 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715040 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915041 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715042
dcheng48459ac22014-08-26 00:46:4115043 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715044
15045 HttpRequestInfo request;
15046 TestCompletionCallback callback;
15047 EXPECT_EQ(ERR_IO_PENDING,
15048 trans.Start(&request, callback.callback(), BoundNetLog()));
15049
15050 base::WeakPtr<FakeStreamRequest> fake_request =
15051 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215052 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715053 EXPECT_EQ(LOW, fake_request->priority());
15054
15055 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215056 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715057 EXPECT_EQ(LOWEST, fake_request->priority());
15058}
15059
[email protected]e86839fd2013-08-14 18:29:0315060// Make sure that HttpNetworkTransaction passes on its priority
15061// updates to its stream.
15062TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915063 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215064 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315065 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915066 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315067
dcheng48459ac22014-08-26 00:46:4115068 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315069
15070 HttpRequestInfo request;
15071 TestCompletionCallback callback;
15072 EXPECT_EQ(ERR_IO_PENDING,
15073 trans.Start(&request, callback.callback(), BoundNetLog()));
15074
15075 base::WeakPtr<FakeStreamRequest> fake_request =
15076 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215077 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315078 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215079 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315080 EXPECT_EQ(LOW, fake_stream->priority());
15081
15082 trans.SetPriority(LOWEST);
15083 EXPECT_EQ(LOWEST, fake_stream->priority());
15084}
15085
[email protected]831e4a32013-11-14 02:14:4415086TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
15087 // The same logic needs to be tested for both ws: and wss: schemes, but this
15088 // test is already parameterised on NextProto, so it uses a loop to verify
15089 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315090 std::string test_cases[] = {"ws://www.example.org/",
15091 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415092 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915093 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215094 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415095 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15096 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315097 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915098 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415099
dcheng48459ac22014-08-26 00:46:4115100 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415101 trans.SetWebSocketHandshakeStreamCreateHelper(
15102 &websocket_stream_create_helper);
15103
15104 HttpRequestInfo request;
15105 TestCompletionCallback callback;
15106 request.method = "GET";
15107 request.url = GURL(test_cases[i]);
15108
15109 EXPECT_EQ(ERR_IO_PENDING,
15110 trans.Start(&request, callback.callback(), BoundNetLog()));
15111
15112 base::WeakPtr<FakeStreamRequest> fake_request =
15113 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215114 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415115 EXPECT_EQ(&websocket_stream_create_helper,
15116 fake_request->websocket_stream_create_helper());
15117 }
15118}
15119
[email protected]043b68c82013-08-22 23:41:5215120// Tests that when a used socket is returned to the SSL socket pool, it's closed
15121// if the transport socket pool is stalled on the global socket limit.
15122TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
15123 ClientSocketPoolManager::set_max_sockets_per_group(
15124 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15125 ClientSocketPoolManager::set_max_sockets_per_pool(
15126 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15127
15128 // Set up SSL request.
15129
15130 HttpRequestInfo ssl_request;
15131 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315132 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215133
15134 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315135 MockWrite(
15136 "GET / HTTP/1.1\r\n"
15137 "Host: www.example.org\r\n"
15138 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215139 };
15140 MockRead ssl_reads[] = {
15141 MockRead("HTTP/1.1 200 OK\r\n"),
15142 MockRead("Content-Length: 11\r\n\r\n"),
15143 MockRead("hello world"),
15144 MockRead(SYNCHRONOUS, OK),
15145 };
15146 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15147 ssl_writes, arraysize(ssl_writes));
15148 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15149
15150 SSLSocketDataProvider ssl(ASYNC, OK);
15151 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15152
15153 // Set up HTTP request.
15154
15155 HttpRequestInfo http_request;
15156 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315157 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215158
15159 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315160 MockWrite(
15161 "GET / HTTP/1.1\r\n"
15162 "Host: www.example.org\r\n"
15163 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215164 };
15165 MockRead http_reads[] = {
15166 MockRead("HTTP/1.1 200 OK\r\n"),
15167 MockRead("Content-Length: 7\r\n\r\n"),
15168 MockRead("falafel"),
15169 MockRead(SYNCHRONOUS, OK),
15170 };
15171 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15172 http_writes, arraysize(http_writes));
15173 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15174
danakj1fd259a02016-04-16 03:17:0915175 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215176
15177 // Start the SSL request.
15178 TestCompletionCallback ssl_callback;
danakj1fd259a02016-04-16 03:17:0915179 std::unique_ptr<HttpTransaction> ssl_trans(
[email protected]043b68c82013-08-22 23:41:5215180 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15181 ASSERT_EQ(ERR_IO_PENDING,
15182 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
15183 BoundNetLog()));
15184
15185 // Start the HTTP request. Pool should stall.
15186 TestCompletionCallback http_callback;
danakj1fd259a02016-04-16 03:17:0915187 std::unique_ptr<HttpTransaction> http_trans(
[email protected]043b68c82013-08-22 23:41:5215188 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15189 ASSERT_EQ(ERR_IO_PENDING,
15190 http_trans->Start(&http_request, http_callback.callback(),
15191 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4115192 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215193
15194 // Wait for response from SSL request.
15195 ASSERT_EQ(OK, ssl_callback.WaitForResult());
15196 std::string response_data;
15197 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
15198 EXPECT_EQ("hello world", response_data);
15199
15200 // The SSL socket should automatically be closed, so the HTTP request can
15201 // start.
dcheng48459ac22014-08-26 00:46:4115202 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15203 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215204
15205 // The HTTP request can now complete.
15206 ASSERT_EQ(OK, http_callback.WaitForResult());
15207 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
15208 EXPECT_EQ("falafel", response_data);
15209
dcheng48459ac22014-08-26 00:46:4115210 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215211}
15212
15213// Tests that when a SSL connection is established but there's no corresponding
15214// request that needs it, the new socket is closed if the transport socket pool
15215// is stalled on the global socket limit.
15216TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
15217 ClientSocketPoolManager::set_max_sockets_per_group(
15218 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15219 ClientSocketPoolManager::set_max_sockets_per_pool(
15220 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15221
15222 // Set up an ssl request.
15223
15224 HttpRequestInfo ssl_request;
15225 ssl_request.method = "GET";
15226 ssl_request.url = GURL("https://www.foopy.com/");
15227
15228 // No data will be sent on the SSL socket.
15229 StaticSocketDataProvider ssl_data;
15230 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15231
15232 SSLSocketDataProvider ssl(ASYNC, OK);
15233 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15234
15235 // Set up HTTP request.
15236
15237 HttpRequestInfo http_request;
15238 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315239 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215240
15241 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315242 MockWrite(
15243 "GET / HTTP/1.1\r\n"
15244 "Host: www.example.org\r\n"
15245 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215246 };
15247 MockRead http_reads[] = {
15248 MockRead("HTTP/1.1 200 OK\r\n"),
15249 MockRead("Content-Length: 7\r\n\r\n"),
15250 MockRead("falafel"),
15251 MockRead(SYNCHRONOUS, OK),
15252 };
15253 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15254 http_writes, arraysize(http_writes));
15255 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15256
danakj1fd259a02016-04-16 03:17:0915257 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215258
15259 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15260 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915261 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915262 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115263 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215264
15265 // Start the HTTP request. Pool should stall.
15266 TestCompletionCallback http_callback;
danakj1fd259a02016-04-16 03:17:0915267 std::unique_ptr<HttpTransaction> http_trans(
[email protected]043b68c82013-08-22 23:41:5215268 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15269 ASSERT_EQ(ERR_IO_PENDING,
15270 http_trans->Start(&http_request, http_callback.callback(),
15271 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4115272 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215273
15274 // The SSL connection will automatically be closed once the connection is
15275 // established, to let the HTTP request start.
15276 ASSERT_EQ(OK, http_callback.WaitForResult());
15277 std::string response_data;
15278 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
15279 EXPECT_EQ("falafel", response_data);
15280
dcheng48459ac22014-08-26 00:46:4115281 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215282}
15283
[email protected]02d74a02014-04-23 18:10:5415284TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915285 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215286 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915287 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215288 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415289
15290 HttpRequestInfo request;
15291 request.method = "POST";
15292 request.url = GURL("http://www.foo.com/");
15293 request.upload_data_stream = &upload_data_stream;
15294 request.load_flags = 0;
15295
danakj1fd259a02016-04-16 03:17:0915296 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15297 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115298 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415299 // Send headers successfully, but get an error while sending the body.
15300 MockWrite data_writes[] = {
15301 MockWrite("POST / HTTP/1.1\r\n"
15302 "Host: www.foo.com\r\n"
15303 "Connection: keep-alive\r\n"
15304 "Content-Length: 3\r\n\r\n"),
15305 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15306 };
15307
15308 MockRead data_reads[] = {
15309 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15310 MockRead("hello world"),
15311 MockRead(SYNCHRONOUS, OK),
15312 };
15313 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15314 arraysize(data_writes));
15315 session_deps_.socket_factory->AddSocketDataProvider(&data);
15316
15317 TestCompletionCallback callback;
15318
15319 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15320 EXPECT_EQ(ERR_IO_PENDING, rv);
15321
15322 rv = callback.WaitForResult();
15323 EXPECT_EQ(OK, rv);
15324
15325 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215326 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415327
wezca1070932016-05-26 20:30:5215328 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415329 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15330
15331 std::string response_data;
15332 rv = ReadTransaction(trans.get(), &response_data);
15333 EXPECT_EQ(OK, rv);
15334 EXPECT_EQ("hello world", response_data);
15335}
15336
15337// This test makes sure the retry logic doesn't trigger when reading an error
15338// response from a server that rejected a POST with a CONNECTION_RESET.
15339TEST_P(HttpNetworkTransactionTest,
15340 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915341 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415342 MockWrite data_writes[] = {
15343 MockWrite("GET / HTTP/1.1\r\n"
15344 "Host: www.foo.com\r\n"
15345 "Connection: keep-alive\r\n\r\n"),
15346 MockWrite("POST / HTTP/1.1\r\n"
15347 "Host: www.foo.com\r\n"
15348 "Connection: keep-alive\r\n"
15349 "Content-Length: 3\r\n\r\n"),
15350 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15351 };
15352
15353 MockRead data_reads[] = {
15354 MockRead("HTTP/1.1 200 Peachy\r\n"
15355 "Content-Length: 14\r\n\r\n"),
15356 MockRead("first response"),
15357 MockRead("HTTP/1.1 400 Not OK\r\n"
15358 "Content-Length: 15\r\n\r\n"),
15359 MockRead("second response"),
15360 MockRead(SYNCHRONOUS, OK),
15361 };
15362 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15363 arraysize(data_writes));
15364 session_deps_.socket_factory->AddSocketDataProvider(&data);
15365
15366 TestCompletionCallback callback;
15367 HttpRequestInfo request1;
15368 request1.method = "GET";
15369 request1.url = GURL("http://www.foo.com/");
15370 request1.load_flags = 0;
15371
danakj1fd259a02016-04-16 03:17:0915372 std::unique_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4115373 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415374 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
15375 EXPECT_EQ(ERR_IO_PENDING, rv);
15376
15377 rv = callback.WaitForResult();
15378 EXPECT_EQ(OK, rv);
15379
15380 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215381 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415382
wezca1070932016-05-26 20:30:5215383 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415384 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15385
15386 std::string response_data1;
15387 rv = ReadTransaction(trans1.get(), &response_data1);
15388 EXPECT_EQ(OK, rv);
15389 EXPECT_EQ("first response", response_data1);
15390 // Delete the transaction to release the socket back into the socket pool.
15391 trans1.reset();
15392
danakj1fd259a02016-04-16 03:17:0915393 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215394 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915395 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215396 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415397
15398 HttpRequestInfo request2;
15399 request2.method = "POST";
15400 request2.url = GURL("http://www.foo.com/");
15401 request2.upload_data_stream = &upload_data_stream;
15402 request2.load_flags = 0;
15403
danakj1fd259a02016-04-16 03:17:0915404 std::unique_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4115405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415406 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
15407 EXPECT_EQ(ERR_IO_PENDING, rv);
15408
15409 rv = callback.WaitForResult();
15410 EXPECT_EQ(OK, rv);
15411
15412 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:5215413 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415414
wezca1070932016-05-26 20:30:5215415 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415416 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15417
15418 std::string response_data2;
15419 rv = ReadTransaction(trans2.get(), &response_data2);
15420 EXPECT_EQ(OK, rv);
15421 EXPECT_EQ("second response", response_data2);
15422}
15423
15424TEST_P(HttpNetworkTransactionTest,
15425 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915426 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215427 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915428 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215429 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415430
15431 HttpRequestInfo request;
15432 request.method = "POST";
15433 request.url = GURL("http://www.foo.com/");
15434 request.upload_data_stream = &upload_data_stream;
15435 request.load_flags = 0;
15436
danakj1fd259a02016-04-16 03:17:0915437 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15438 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115439 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415440 // Send headers successfully, but get an error while sending the body.
15441 MockWrite data_writes[] = {
15442 MockWrite("POST / HTTP/1.1\r\n"
15443 "Host: www.foo.com\r\n"
15444 "Connection: keep-alive\r\n"
15445 "Content-Length: 3\r\n\r\n"
15446 "fo"),
15447 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15448 };
15449
15450 MockRead data_reads[] = {
15451 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15452 MockRead("hello world"),
15453 MockRead(SYNCHRONOUS, OK),
15454 };
15455 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15456 arraysize(data_writes));
15457 session_deps_.socket_factory->AddSocketDataProvider(&data);
15458
15459 TestCompletionCallback callback;
15460
15461 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15462 EXPECT_EQ(ERR_IO_PENDING, rv);
15463
15464 rv = callback.WaitForResult();
15465 EXPECT_EQ(OK, rv);
15466
15467 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215468 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415469
wezca1070932016-05-26 20:30:5215470 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415471 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15472
15473 std::string response_data;
15474 rv = ReadTransaction(trans.get(), &response_data);
15475 EXPECT_EQ(OK, rv);
15476 EXPECT_EQ("hello world", response_data);
15477}
15478
15479// This tests the more common case than the previous test, where headers and
15480// body are not merged into a single request.
15481TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715482 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415483
15484 HttpRequestInfo request;
15485 request.method = "POST";
15486 request.url = GURL("http://www.foo.com/");
15487 request.upload_data_stream = &upload_data_stream;
15488 request.load_flags = 0;
15489
danakj1fd259a02016-04-16 03:17:0915490 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15491 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115492 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415493 // Send headers successfully, but get an error while sending the body.
15494 MockWrite data_writes[] = {
15495 MockWrite("POST / HTTP/1.1\r\n"
15496 "Host: www.foo.com\r\n"
15497 "Connection: keep-alive\r\n"
15498 "Transfer-Encoding: chunked\r\n\r\n"),
15499 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15500 };
15501
15502 MockRead data_reads[] = {
15503 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15504 MockRead("hello world"),
15505 MockRead(SYNCHRONOUS, OK),
15506 };
15507 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15508 arraysize(data_writes));
15509 session_deps_.socket_factory->AddSocketDataProvider(&data);
15510
15511 TestCompletionCallback callback;
15512
15513 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15514 EXPECT_EQ(ERR_IO_PENDING, rv);
15515 // Make sure the headers are sent before adding a chunk. This ensures that
15516 // they can't be merged with the body in a single send. Not currently
15517 // necessary since a chunked body is never merged with headers, but this makes
15518 // the test more future proof.
15519 base::RunLoop().RunUntilIdle();
15520
mmenkecbc2b712014-10-09 20:29:0715521 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415522
15523 rv = callback.WaitForResult();
15524 EXPECT_EQ(OK, rv);
15525
15526 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215527 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415528
wezca1070932016-05-26 20:30:5215529 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415530 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15531
15532 std::string response_data;
15533 rv = ReadTransaction(trans.get(), &response_data);
15534 EXPECT_EQ(OK, rv);
15535 EXPECT_EQ("hello world", response_data);
15536}
15537
15538TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915539 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215540 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915541 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215542 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415543
15544 HttpRequestInfo request;
15545 request.method = "POST";
15546 request.url = GURL("http://www.foo.com/");
15547 request.upload_data_stream = &upload_data_stream;
15548 request.load_flags = 0;
15549
danakj1fd259a02016-04-16 03:17:0915550 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15551 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115552 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415553
15554 MockWrite data_writes[] = {
15555 MockWrite("POST / HTTP/1.1\r\n"
15556 "Host: www.foo.com\r\n"
15557 "Connection: keep-alive\r\n"
15558 "Content-Length: 3\r\n\r\n"),
15559 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15560 };
15561
15562 MockRead data_reads[] = {
15563 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15564 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15565 MockRead("hello world"),
15566 MockRead(SYNCHRONOUS, OK),
15567 };
15568 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15569 arraysize(data_writes));
15570 session_deps_.socket_factory->AddSocketDataProvider(&data);
15571
15572 TestCompletionCallback callback;
15573
15574 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15575 EXPECT_EQ(ERR_IO_PENDING, rv);
15576
15577 rv = callback.WaitForResult();
15578 EXPECT_EQ(OK, rv);
15579
15580 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215581 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415582
wezca1070932016-05-26 20:30:5215583 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415584 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15585
15586 std::string response_data;
15587 rv = ReadTransaction(trans.get(), &response_data);
15588 EXPECT_EQ(OK, rv);
15589 EXPECT_EQ("hello world", response_data);
15590}
15591
15592TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915593 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215594 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915595 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215596 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415597
15598 HttpRequestInfo request;
15599 request.method = "POST";
15600 request.url = GURL("http://www.foo.com/");
15601 request.upload_data_stream = &upload_data_stream;
15602 request.load_flags = 0;
15603
danakj1fd259a02016-04-16 03:17:0915604 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15605 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115606 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415607 // Send headers successfully, but get an error while sending the body.
15608 MockWrite data_writes[] = {
15609 MockWrite("POST / HTTP/1.1\r\n"
15610 "Host: www.foo.com\r\n"
15611 "Connection: keep-alive\r\n"
15612 "Content-Length: 3\r\n\r\n"),
15613 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15614 };
15615
15616 MockRead data_reads[] = {
15617 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15618 MockRead("hello world"),
15619 MockRead(SYNCHRONOUS, OK),
15620 };
15621 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15622 arraysize(data_writes));
15623 session_deps_.socket_factory->AddSocketDataProvider(&data);
15624
15625 TestCompletionCallback callback;
15626
15627 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15628 EXPECT_EQ(ERR_IO_PENDING, rv);
15629
15630 rv = callback.WaitForResult();
15631 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415632}
15633
15634TEST_P(HttpNetworkTransactionTest,
15635 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915636 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215637 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915638 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215639 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415640
15641 HttpRequestInfo request;
15642 request.method = "POST";
15643 request.url = GURL("http://www.foo.com/");
15644 request.upload_data_stream = &upload_data_stream;
15645 request.load_flags = 0;
15646
danakj1fd259a02016-04-16 03:17:0915647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15648 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115649 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415650 // Send headers successfully, but get an error while sending the body.
15651 MockWrite data_writes[] = {
15652 MockWrite("POST / HTTP/1.1\r\n"
15653 "Host: www.foo.com\r\n"
15654 "Connection: keep-alive\r\n"
15655 "Content-Length: 3\r\n\r\n"),
15656 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15657 };
15658
15659 MockRead data_reads[] = {
15660 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15661 MockRead("HTTP/1.0 302 Redirect\r\n"),
15662 MockRead("Location: http://somewhere-else.com/\r\n"),
15663 MockRead("Content-Length: 0\r\n\r\n"),
15664 MockRead(SYNCHRONOUS, OK),
15665 };
15666 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15667 arraysize(data_writes));
15668 session_deps_.socket_factory->AddSocketDataProvider(&data);
15669
15670 TestCompletionCallback callback;
15671
15672 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15673 EXPECT_EQ(ERR_IO_PENDING, rv);
15674
15675 rv = callback.WaitForResult();
15676 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415677}
15678
15679TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915680 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215681 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915682 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215683 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415684
15685 HttpRequestInfo request;
15686 request.method = "POST";
15687 request.url = GURL("http://www.foo.com/");
15688 request.upload_data_stream = &upload_data_stream;
15689 request.load_flags = 0;
15690
danakj1fd259a02016-04-16 03:17:0915691 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15692 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115693 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415694 // Send headers successfully, but get an error while sending the body.
15695 MockWrite data_writes[] = {
15696 MockWrite("POST / HTTP/1.1\r\n"
15697 "Host: www.foo.com\r\n"
15698 "Connection: keep-alive\r\n"
15699 "Content-Length: 3\r\n\r\n"),
15700 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15701 };
15702
15703 MockRead data_reads[] = {
15704 MockRead("HTTP 0.9 rocks!"),
15705 MockRead(SYNCHRONOUS, OK),
15706 };
15707 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15708 arraysize(data_writes));
15709 session_deps_.socket_factory->AddSocketDataProvider(&data);
15710
15711 TestCompletionCallback callback;
15712
15713 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15714 EXPECT_EQ(ERR_IO_PENDING, rv);
15715
15716 rv = callback.WaitForResult();
15717 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415718}
15719
15720TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0915721 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215722 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915723 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215724 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415725
15726 HttpRequestInfo request;
15727 request.method = "POST";
15728 request.url = GURL("http://www.foo.com/");
15729 request.upload_data_stream = &upload_data_stream;
15730 request.load_flags = 0;
15731
danakj1fd259a02016-04-16 03:17:0915732 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15733 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115734 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415735 // Send headers successfully, but get an error while sending the body.
15736 MockWrite data_writes[] = {
15737 MockWrite("POST / HTTP/1.1\r\n"
15738 "Host: www.foo.com\r\n"
15739 "Connection: keep-alive\r\n"
15740 "Content-Length: 3\r\n\r\n"),
15741 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15742 };
15743
15744 MockRead data_reads[] = {
15745 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15746 MockRead(SYNCHRONOUS, OK),
15747 };
15748 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15749 arraysize(data_writes));
15750 session_deps_.socket_factory->AddSocketDataProvider(&data);
15751
15752 TestCompletionCallback callback;
15753
15754 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15755 EXPECT_EQ(ERR_IO_PENDING, rv);
15756
15757 rv = callback.WaitForResult();
15758 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415759}
15760
Adam Rice425cf122015-01-19 06:18:2415761// Verify that proxy headers are not sent to the destination server when
15762// establishing a tunnel for a secure WebSocket connection.
15763TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
15764 HttpRequestInfo request;
15765 request.method = "GET";
bncce36dca22015-04-21 22:11:2315766 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415767 AddWebSocketHeaders(&request.extra_headers);
15768
15769 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315770 session_deps_.proxy_service =
15771 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415772
danakj1fd259a02016-04-16 03:17:0915773 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415774
15775 // Since a proxy is configured, try to establish a tunnel.
15776 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715777 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15778 "Host: www.example.org:443\r\n"
15779 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415780
15781 // After calling trans->RestartWithAuth(), this is the request we should
15782 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1715783 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15784 "Host: www.example.org:443\r\n"
15785 "Proxy-Connection: keep-alive\r\n"
15786 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415787
rsleevidb16bb02015-11-12 23:47:1715788 MockWrite("GET / HTTP/1.1\r\n"
15789 "Host: www.example.org\r\n"
15790 "Connection: Upgrade\r\n"
15791 "Upgrade: websocket\r\n"
15792 "Origin: http://www.example.org\r\n"
15793 "Sec-WebSocket-Version: 13\r\n"
15794 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415795 };
15796
15797 // The proxy responds to the connect with a 407, using a persistent
15798 // connection.
15799 MockRead data_reads[] = {
15800 // No credentials.
15801 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15802 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415803 MockRead("Content-Length: 0\r\n"),
15804 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415805
15806 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15807
15808 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15809 MockRead("Upgrade: websocket\r\n"),
15810 MockRead("Connection: Upgrade\r\n"),
15811 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15812 };
15813
15814 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15815 arraysize(data_writes));
15816 session_deps_.socket_factory->AddSocketDataProvider(&data);
15817 SSLSocketDataProvider ssl(ASYNC, OK);
15818 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15819
danakj1fd259a02016-04-16 03:17:0915820 std::unique_ptr<HttpTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415821 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15822 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15823 trans->SetWebSocketHandshakeStreamCreateHelper(
15824 &websocket_stream_create_helper);
15825
15826 {
15827 TestCompletionCallback callback;
15828
15829 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15830 EXPECT_EQ(ERR_IO_PENDING, rv);
15831
15832 rv = callback.WaitForResult();
15833 EXPECT_EQ(OK, rv);
15834 }
15835
15836 const HttpResponseInfo* response = trans->GetResponseInfo();
15837 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215838 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415839 EXPECT_EQ(407, response->headers->response_code());
15840
15841 {
15842 TestCompletionCallback callback;
15843
15844 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15845 callback.callback());
15846 EXPECT_EQ(ERR_IO_PENDING, rv);
15847
15848 rv = callback.WaitForResult();
15849 EXPECT_EQ(OK, rv);
15850 }
15851
15852 response = trans->GetResponseInfo();
15853 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215854 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415855
15856 EXPECT_EQ(101, response->headers->response_code());
15857
15858 trans.reset();
15859 session->CloseAllConnections();
15860}
15861
15862// Verify that proxy headers are not sent to the destination server when
15863// establishing a tunnel for an insecure WebSocket connection.
15864// This requires the authentication info to be injected into the auth cache
15865// due to crbug.com/395064
15866// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
15867TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
15868 HttpRequestInfo request;
15869 request.method = "GET";
bncce36dca22015-04-21 22:11:2315870 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415871 AddWebSocketHeaders(&request.extra_headers);
15872
15873 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315874 session_deps_.proxy_service =
15875 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415876
danakj1fd259a02016-04-16 03:17:0915877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415878
15879 MockWrite data_writes[] = {
15880 // Try to establish a tunnel for the WebSocket connection, with
15881 // credentials. Because WebSockets have a separate set of socket pools,
15882 // they cannot and will not use the same TCP/IP connection as the
15883 // preflight HTTP request.
15884 MockWrite(
bncce36dca22015-04-21 22:11:2315885 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15886 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415887 "Proxy-Connection: keep-alive\r\n"
15888 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15889
15890 MockWrite(
15891 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315892 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415893 "Connection: Upgrade\r\n"
15894 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315895 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415896 "Sec-WebSocket-Version: 13\r\n"
15897 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15898 };
15899
15900 MockRead data_reads[] = {
15901 // HTTP CONNECT with credentials.
15902 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15903
15904 // WebSocket connection established inside tunnel.
15905 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15906 MockRead("Upgrade: websocket\r\n"),
15907 MockRead("Connection: Upgrade\r\n"),
15908 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15909 };
15910
15911 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15912 arraysize(data_writes));
15913 session_deps_.socket_factory->AddSocketDataProvider(&data);
15914
15915 session->http_auth_cache()->Add(
15916 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
15917 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
15918
danakj1fd259a02016-04-16 03:17:0915919 std::unique_ptr<HttpTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415920 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15921 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15922 trans->SetWebSocketHandshakeStreamCreateHelper(
15923 &websocket_stream_create_helper);
15924
15925 TestCompletionCallback callback;
15926
15927 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15928 EXPECT_EQ(ERR_IO_PENDING, rv);
15929
15930 rv = callback.WaitForResult();
15931 EXPECT_EQ(OK, rv);
15932
15933 const HttpResponseInfo* response = trans->GetResponseInfo();
15934 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215935 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415936
15937 EXPECT_EQ(101, response->headers->response_code());
15938
15939 trans.reset();
15940 session->CloseAllConnections();
15941}
15942
sclittlefb249892015-09-10 21:33:2215943TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0915944 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215945 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915946 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215947 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215948
15949 HttpRequestInfo request;
15950 request.method = "POST";
15951 request.url = GURL("http://www.foo.com/");
15952 request.upload_data_stream = &upload_data_stream;
15953
danakj1fd259a02016-04-16 03:17:0915954 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15955 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2215956 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15957 MockWrite data_writes[] = {
15958 MockWrite("POST / HTTP/1.1\r\n"
15959 "Host: www.foo.com\r\n"
15960 "Connection: keep-alive\r\n"
15961 "Content-Length: 3\r\n\r\n"),
15962 MockWrite("foo"),
15963 };
15964
15965 MockRead data_reads[] = {
15966 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15967 MockRead(SYNCHRONOUS, OK),
15968 };
15969 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15970 arraysize(data_writes));
15971 session_deps_.socket_factory->AddSocketDataProvider(&data);
15972
15973 TestCompletionCallback callback;
15974
15975 EXPECT_EQ(ERR_IO_PENDING,
15976 trans->Start(&request, callback.callback(), BoundNetLog()));
15977 EXPECT_EQ(OK, callback.WaitForResult());
15978
15979 std::string response_data;
15980 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15981
15982 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15983 trans->GetTotalSentBytes());
15984 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15985 trans->GetTotalReceivedBytes());
15986}
15987
15988TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0915989 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215990 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915991 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215992 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215993
15994 HttpRequestInfo request;
15995 request.method = "POST";
15996 request.url = GURL("http://www.foo.com/");
15997 request.upload_data_stream = &upload_data_stream;
15998
danakj1fd259a02016-04-16 03:17:0915999 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16000 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2216001 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16002 MockWrite data_writes[] = {
16003 MockWrite("POST / HTTP/1.1\r\n"
16004 "Host: www.foo.com\r\n"
16005 "Connection: keep-alive\r\n"
16006 "Content-Length: 3\r\n\r\n"),
16007 MockWrite("foo"),
16008 };
16009
16010 MockRead data_reads[] = {
16011 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16012 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16013 MockRead(SYNCHRONOUS, OK),
16014 };
16015 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16016 arraysize(data_writes));
16017 session_deps_.socket_factory->AddSocketDataProvider(&data);
16018
16019 TestCompletionCallback callback;
16020
16021 EXPECT_EQ(ERR_IO_PENDING,
16022 trans->Start(&request, callback.callback(), BoundNetLog()));
16023 EXPECT_EQ(OK, callback.WaitForResult());
16024
16025 std::string response_data;
16026 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
16027
16028 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
16029 trans->GetTotalSentBytes());
16030 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
16031 trans->GetTotalReceivedBytes());
16032}
16033
16034TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216035 ChunkedUploadDataStream upload_data_stream(0);
16036
16037 HttpRequestInfo request;
16038 request.method = "POST";
16039 request.url = GURL("http://www.foo.com/");
16040 request.upload_data_stream = &upload_data_stream;
16041
danakj1fd259a02016-04-16 03:17:0916042 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16043 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2216044 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16045 // Send headers successfully, but get an error while sending the body.
16046 MockWrite data_writes[] = {
16047 MockWrite("POST / HTTP/1.1\r\n"
16048 "Host: www.foo.com\r\n"
16049 "Connection: keep-alive\r\n"
16050 "Transfer-Encoding: chunked\r\n\r\n"),
16051 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16052 };
16053
16054 MockRead data_reads[] = {
16055 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16056 MockRead(SYNCHRONOUS, OK),
16057 };
16058 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16059 arraysize(data_writes));
16060 session_deps_.socket_factory->AddSocketDataProvider(&data);
16061
16062 TestCompletionCallback callback;
16063
16064 EXPECT_EQ(ERR_IO_PENDING,
16065 trans->Start(&request, callback.callback(), BoundNetLog()));
16066
16067 base::RunLoop().RunUntilIdle();
16068 upload_data_stream.AppendData("f", 1, false);
16069
16070 base::RunLoop().RunUntilIdle();
16071 upload_data_stream.AppendData("oo", 2, true);
16072
16073 EXPECT_EQ(OK, callback.WaitForResult());
16074
16075 std::string response_data;
16076 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
16077
16078 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
16079 trans->GetTotalSentBytes());
16080 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
16081 trans->GetTotalReceivedBytes());
16082}
16083
bncf4588402015-11-24 13:33:1816084TEST_P(HttpNetworkTransactionTest, EnableNPN) {
bncf4588402015-11-24 13:33:1816085 session_deps_.enable_npn = true;
16086
danakj1fd259a02016-04-16 03:17:0916087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncf4588402015-11-24 13:33:1816088 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
nharper8cdb0fb2016-04-22 21:34:5916089 HttpRequestInfo request;
16090 TestCompletionCallback callback;
16091 EXPECT_EQ(ERR_IO_PENDING,
16092 trans.Start(&request, callback.callback(), BoundNetLog()));
bncf4588402015-11-24 13:33:1816093
16094 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
16095 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
16096 EXPECT_THAT(trans.server_ssl_config_.npn_protos,
16097 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
16098}
16099
16100TEST_P(HttpNetworkTransactionTest, DisableNPN) {
bncf4588402015-11-24 13:33:1816101 session_deps_.enable_npn = false;
16102
danakj1fd259a02016-04-16 03:17:0916103 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncf4588402015-11-24 13:33:1816104 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
nharper8cdb0fb2016-04-22 21:34:5916105 HttpRequestInfo request;
16106 TestCompletionCallback callback;
16107 EXPECT_EQ(ERR_IO_PENDING,
16108 trans.Start(&request, callback.callback(), BoundNetLog()));
bncf4588402015-11-24 13:33:1816109
16110 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
16111 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
16112 EXPECT_TRUE(trans.server_ssl_config_.npn_protos.empty());
16113}
16114
nharperb7441ef2016-01-25 23:54:1416115#if !defined(OS_IOS)
16116TEST_P(HttpNetworkTransactionTest, TokenBindingSpdy) {
16117 const std::string https_url = "https://www.example.com";
16118 HttpRequestInfo request;
16119 request.url = GURL(https_url);
16120 request.method = "GET";
16121
16122 SSLSocketDataProvider ssl(ASYNC, OK);
16123 ssl.token_binding_negotiated = true;
16124 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
16125 ssl.SetNextProto(GetProtocol());
16126 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16127
danakj1fd259a02016-04-16 03:17:0916128 std::unique_ptr<SpdySerializedFrame> resp(
nharperb7441ef2016-01-25 23:54:1416129 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0916130 std::unique_ptr<SpdySerializedFrame> body(
bncb03b1092016-04-06 11:19:5516131 spdy_util_.ConstructSpdyBodyFrame(1, true));
nharperb7441ef2016-01-25 23:54:1416132 MockRead reads[] = {CreateMockRead(*resp), CreateMockRead(*body),
16133 MockRead(ASYNC, ERR_IO_PENDING)};
16134 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16135 session_deps_.socket_factory->AddSocketDataProvider(&data);
16136 session_deps_.channel_id_service.reset(new ChannelIDService(
16137 new DefaultChannelIDStore(nullptr), base::ThreadTaskRunnerHandle::Get()));
danakj1fd259a02016-04-16 03:17:0916138 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416139
16140 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16141 TestCompletionCallback callback;
16142 EXPECT_EQ(ERR_IO_PENDING,
16143 trans.Start(&request, callback.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5516144 base::RunLoop().RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416145
16146 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16147 HttpRequestHeaders headers;
16148 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16149 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16150}
16151#endif // !defined(OS_IOS)
16152
[email protected]89ceba9a2009-03-21 03:46:0616153} // namespace net