blob: 8f59f36108f6e925a529b6d320dd1d856b274ba9 [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);
bncce36dca22015-04-21 22:11:23680 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[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);
690 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
691 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19692 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04693 return true;
694}
695
696bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
697 if (!auth_challenge)
698 return false;
699 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23700 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04701 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19702 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04703 return true;
704}
705
thakis84dff942015-07-28 20:47:38706#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04707bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
708 if (!auth_challenge)
709 return false;
710 EXPECT_FALSE(auth_challenge->is_proxy);
711 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
712 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19713 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04714 return true;
715}
thakis84dff942015-07-28 20:47:38716#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04717
[email protected]448d4ca52012-03-04 04:12:23718} // namespace
719
[email protected]23e482282013-06-14 16:08:02720TEST_P(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09721 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
722 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41723 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27724}
725
[email protected]23e482282013-06-14 16:08:02726TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27727 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35728 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
729 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06730 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27731 };
[email protected]31a2bfe2010-02-09 08:03:39732 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
733 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42734 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27735 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
736 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22737 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
738 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47739 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59740
741 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27742}
743
744// Response with no status line.
[email protected]23e482282013-06-14 16:08:02745TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27746 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35747 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06748 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27749 };
[email protected]31a2bfe2010-02-09 08:03:39750 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
751 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42752 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27753 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
754 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22755 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
756 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27757}
758
759// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02760TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27761 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35762 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06763 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27764 };
[email protected]31a2bfe2010-02-09 08:03:39765 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
766 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42767 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27768 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
769 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22770 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
771 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27772}
773
774// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02775TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27776 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35777 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06778 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27779 };
[email protected]31a2bfe2010-02-09 08:03:39780 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
781 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42782 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27783 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
784 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22785 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
786 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27787}
788
789// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02790TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27791 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35792 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06793 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27794 };
[email protected]31a2bfe2010-02-09 08:03:39795 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
796 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42797 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25798 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
799 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
sclittlefb249892015-09-10 21:33:22800 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
801 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27802}
803
804// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02805TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27806 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35807 MockRead("\n"),
808 MockRead("\n"),
809 MockRead("Q"),
810 MockRead("J"),
811 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06812 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27813 };
[email protected]31a2bfe2010-02-09 08:03:39814 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
815 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42816 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27817 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
818 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22819 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
820 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27821}
822
823// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02824TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27825 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35826 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06827 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27828 };
[email protected]31a2bfe2010-02-09 08:03:39829 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
830 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42831 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27832 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
833 EXPECT_EQ("HTT", out.response_data);
sclittlefb249892015-09-10 21:33:22834 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
835 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52836}
837
[email protected]f9d44aa2008-09-23 23:57:17838// Simulate a 204 response, lacking a Content-Length header, sent over a
839// persistent connection. The response should still terminate since a 204
840// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02841TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19842 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17843 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35844 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19845 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06846 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17847 };
[email protected]31a2bfe2010-02-09 08:03:39848 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
849 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42850 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17851 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
852 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22853 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
854 int64_t response_size = reads_size - strlen(junk);
855 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17856}
857
[email protected]0877e3d2009-10-17 22:29:57858// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02859TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19860 std::string final_chunk = "0\r\n\r\n";
861 std::string extra_data = "HTTP/1.1 200 OK\r\n";
862 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57863 MockRead data_reads[] = {
864 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
865 MockRead("5\r\nHello\r\n"),
866 MockRead("1\r\n"),
867 MockRead(" \r\n"),
868 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19869 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06870 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57871 };
[email protected]31a2bfe2010-02-09 08:03:39872 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
873 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57874 EXPECT_EQ(OK, out.rv);
875 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
876 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22877 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
878 int64_t response_size = reads_size - extra_data.size();
879 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57880}
881
[email protected]9fe44f52010-09-23 18:36:00882// Next tests deal with http://crbug.com/56344.
883
[email protected]23e482282013-06-14 16:08:02884TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00885 MultipleContentLengthHeadersNoTransferEncoding) {
886 MockRead data_reads[] = {
887 MockRead("HTTP/1.1 200 OK\r\n"),
888 MockRead("Content-Length: 10\r\n"),
889 MockRead("Content-Length: 5\r\n\r\n"),
890 };
891 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
892 arraysize(data_reads));
893 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
894}
895
[email protected]23e482282013-06-14 16:08:02896TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04897 DuplicateContentLengthHeadersNoTransferEncoding) {
898 MockRead data_reads[] = {
899 MockRead("HTTP/1.1 200 OK\r\n"),
900 MockRead("Content-Length: 5\r\n"),
901 MockRead("Content-Length: 5\r\n\r\n"),
902 MockRead("Hello"),
903 };
904 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
905 arraysize(data_reads));
906 EXPECT_EQ(OK, out.rv);
907 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
908 EXPECT_EQ("Hello", out.response_data);
909}
910
[email protected]23e482282013-06-14 16:08:02911TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04912 ComplexContentLengthHeadersNoTransferEncoding) {
913 // More than 2 dupes.
914 {
915 MockRead data_reads[] = {
916 MockRead("HTTP/1.1 200 OK\r\n"),
917 MockRead("Content-Length: 5\r\n"),
918 MockRead("Content-Length: 5\r\n"),
919 MockRead("Content-Length: 5\r\n\r\n"),
920 MockRead("Hello"),
921 };
922 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
923 arraysize(data_reads));
924 EXPECT_EQ(OK, out.rv);
925 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
926 EXPECT_EQ("Hello", out.response_data);
927 }
928 // HTTP/1.0
929 {
930 MockRead data_reads[] = {
931 MockRead("HTTP/1.0 200 OK\r\n"),
932 MockRead("Content-Length: 5\r\n"),
933 MockRead("Content-Length: 5\r\n"),
934 MockRead("Content-Length: 5\r\n\r\n"),
935 MockRead("Hello"),
936 };
937 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
938 arraysize(data_reads));
939 EXPECT_EQ(OK, out.rv);
940 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
941 EXPECT_EQ("Hello", out.response_data);
942 }
943 // 2 dupes and one mismatched.
944 {
945 MockRead data_reads[] = {
946 MockRead("HTTP/1.1 200 OK\r\n"),
947 MockRead("Content-Length: 10\r\n"),
948 MockRead("Content-Length: 10\r\n"),
949 MockRead("Content-Length: 5\r\n\r\n"),
950 };
951 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
952 arraysize(data_reads));
953 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
954 }
955}
956
[email protected]23e482282013-06-14 16:08:02957TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00958 MultipleContentLengthHeadersTransferEncoding) {
959 MockRead data_reads[] = {
960 MockRead("HTTP/1.1 200 OK\r\n"),
961 MockRead("Content-Length: 666\r\n"),
962 MockRead("Content-Length: 1337\r\n"),
963 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
964 MockRead("5\r\nHello\r\n"),
965 MockRead("1\r\n"),
966 MockRead(" \r\n"),
967 MockRead("5\r\nworld\r\n"),
968 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06969 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00970 };
971 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
972 arraysize(data_reads));
973 EXPECT_EQ(OK, out.rv);
974 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
975 EXPECT_EQ("Hello world", out.response_data);
976}
977
[email protected]1628fe92011-10-04 23:04:55978// Next tests deal with http://crbug.com/98895.
979
980// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02981TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55982 MockRead data_reads[] = {
983 MockRead("HTTP/1.1 200 OK\r\n"),
984 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
985 MockRead("Content-Length: 5\r\n\r\n"),
986 MockRead("Hello"),
987 };
988 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
989 arraysize(data_reads));
990 EXPECT_EQ(OK, out.rv);
991 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
992 EXPECT_EQ("Hello", out.response_data);
993}
994
[email protected]54a9c6e52012-03-21 20:10:59995// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02996TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59997 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55998 MockRead data_reads[] = {
999 MockRead("HTTP/1.1 200 OK\r\n"),
1000 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1001 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1002 MockRead("Content-Length: 5\r\n\r\n"),
1003 MockRead("Hello"),
1004 };
1005 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1006 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:591007 EXPECT_EQ(OK, out.rv);
1008 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1009 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551010}
1011
1012// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:021013TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551014 MockRead data_reads[] = {
1015 MockRead("HTTP/1.1 200 OK\r\n"),
1016 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1017 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1018 MockRead("Content-Length: 5\r\n\r\n"),
1019 MockRead("Hello"),
1020 };
1021 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1022 arraysize(data_reads));
1023 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
1024}
1025
[email protected]54a9c6e52012-03-21 20:10:591026// Checks that two identical Location headers result in no error.
1027// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:021028TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551029 MockRead data_reads[] = {
1030 MockRead("HTTP/1.1 302 Redirect\r\n"),
1031 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591032 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551033 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061034 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551035 };
1036
1037 HttpRequestInfo request;
1038 request.method = "GET";
1039 request.url = GURL("http://redirect.com/");
1040 request.load_flags = 0;
1041
danakj1fd259a02016-04-16 03:17:091042 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1043 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411044 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:551045
1046 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071047 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551048
[email protected]49639fa2011-12-20 23:22:411049 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551050
[email protected]49639fa2011-12-20 23:22:411051 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:551052 EXPECT_EQ(ERR_IO_PENDING, rv);
1053
1054 EXPECT_EQ(OK, callback.WaitForResult());
1055
1056 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521057 ASSERT_TRUE(response);
1058 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551059 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1060 std::string url;
1061 EXPECT_TRUE(response->headers->IsRedirect(&url));
1062 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151063 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551064}
1065
[email protected]1628fe92011-10-04 23:04:551066// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021067TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551068 MockRead data_reads[] = {
1069 MockRead("HTTP/1.1 302 Redirect\r\n"),
1070 MockRead("Location: http://good.com/\r\n"),
1071 MockRead("Location: http://evil.com/\r\n"),
1072 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061073 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551074 };
1075 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1076 arraysize(data_reads));
1077 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1078}
1079
[email protected]ef0faf2e72009-03-05 23:27:231080// Do a request using the HEAD method. Verify that we don't try to read the
1081// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021082TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421083 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231084 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231085 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231086 request.load_flags = 0;
1087
danakj1fd259a02016-04-16 03:17:091088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1089 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411090 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ryansturm49a8cb12016-06-15 16:51:091091 BeforeHeadersSentHandler headers_handler;
1092 trans->SetBeforeHeadersSentCallback(
1093 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1094 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271095
[email protected]ef0faf2e72009-03-05 23:27:231096 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131097 MockWrite("HEAD / HTTP/1.1\r\n"
1098 "Host: www.example.org\r\n"
1099 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231100 };
1101 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231102 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1103 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231104
mmenked39192ee2015-12-09 00:57:231105 // No response body because the test stops reading here.
1106 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231107 };
1108
[email protected]31a2bfe2010-02-09 08:03:391109 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1110 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071111 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231112
[email protected]49639fa2011-12-20 23:22:411113 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231114
[email protected]49639fa2011-12-20 23:22:411115 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421116 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231117
1118 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421119 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231120
[email protected]1c773ea12009-04-28 19:58:421121 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521122 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231123
1124 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521125 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231126 EXPECT_EQ(1234, response->headers->GetContentLength());
1127 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151128 EXPECT_TRUE(response->proxy_server.IsEmpty());
ryansturm49a8cb12016-06-15 16:51:091129 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1130 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231131
1132 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101133 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231134 bool has_server_header = response->headers->EnumerateHeader(
1135 &iter, "Server", &server_header);
1136 EXPECT_TRUE(has_server_header);
1137 EXPECT_EQ("Blah", server_header);
1138
1139 // Reading should give EOF right away, since there is no message body
1140 // (despite non-zero content-length).
1141 std::string response_data;
1142 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421143 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231144 EXPECT_EQ("", response_data);
1145}
1146
[email protected]23e482282013-06-14 16:08:021147TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091148 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521149
1150 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351151 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1152 MockRead("hello"),
1153 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1154 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061155 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521156 };
[email protected]31a2bfe2010-02-09 08:03:391157 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071158 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521159
[email protected]0b0bf032010-09-21 18:08:501160 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521161 "hello", "world"
1162 };
1163
1164 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421165 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521166 request.method = "GET";
bncce36dca22015-04-21 22:11:231167 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521168 request.load_flags = 0;
1169
danakj1fd259a02016-04-16 03:17:091170 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501171 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271172
[email protected]49639fa2011-12-20 23:22:411173 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521174
[email protected]49639fa2011-12-20 23:22:411175 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421176 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521177
1178 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421179 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521180
[email protected]1c773ea12009-04-28 19:58:421181 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521182 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521183
wezca1070932016-05-26 20:30:521184 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251185 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151186 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521187
1188 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571189 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421190 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251191 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521192 }
1193}
1194
[email protected]23e482282013-06-14 16:08:021195TEST_P(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091196 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221197 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:091198 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:221199 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271200
[email protected]1c773ea12009-04-28 19:58:421201 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521202 request.method = "POST";
1203 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271204 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521205 request.load_flags = 0;
1206
danakj1fd259a02016-04-16 03:17:091207 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1208 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271210
initial.commit586acc5fe2008-07-26 22:42:521211 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351212 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1213 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1214 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061215 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521216 };
[email protected]31a2bfe2010-02-09 08:03:391217 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071218 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521219
[email protected]49639fa2011-12-20 23:22:411220 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521221
[email protected]49639fa2011-12-20 23:22:411222 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421223 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521224
1225 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421226 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521227
[email protected]1c773ea12009-04-28 19:58:421228 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521229 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521230
wezca1070932016-05-26 20:30:521231 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251232 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521233
1234 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571235 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421236 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251237 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521238}
1239
[email protected]3a2d3662009-03-27 03:49:141240// This test is almost the same as Ignores100 above, but the response contains
1241// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571242// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021243TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421244 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141245 request.method = "GET";
1246 request.url = GURL("http://www.foo.com/");
1247 request.load_flags = 0;
1248
danakj1fd259a02016-04-16 03:17:091249 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1250 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411251 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271252
[email protected]3a2d3662009-03-27 03:49:141253 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571254 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1255 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141256 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061257 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141258 };
[email protected]31a2bfe2010-02-09 08:03:391259 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071260 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141261
[email protected]49639fa2011-12-20 23:22:411262 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141263
[email protected]49639fa2011-12-20 23:22:411264 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421265 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141266
1267 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421268 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141269
[email protected]1c773ea12009-04-28 19:58:421270 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521271 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141272
wezca1070932016-05-26 20:30:521273 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141274 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1275
1276 std::string response_data;
1277 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421278 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141279 EXPECT_EQ("hello world", response_data);
1280}
1281
[email protected]23e482282013-06-14 16:08:021282TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081283 HttpRequestInfo request;
1284 request.method = "POST";
1285 request.url = GURL("http://www.foo.com/");
1286 request.load_flags = 0;
1287
danakj1fd259a02016-04-16 03:17:091288 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1289 std::unique_ptr<HttpTransaction> trans(
zmo9528c9f42015-08-04 22:12:081290 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1291
1292 MockRead data_reads[] = {
1293 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1294 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381295 };
zmo9528c9f42015-08-04 22:12:081296 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1297 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381298
zmo9528c9f42015-08-04 22:12:081299 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381300
zmo9528c9f42015-08-04 22:12:081301 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1302 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381303
zmo9528c9f42015-08-04 22:12:081304 rv = callback.WaitForResult();
1305 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381306
zmo9528c9f42015-08-04 22:12:081307 std::string response_data;
1308 rv = ReadTransaction(trans.get(), &response_data);
1309 EXPECT_EQ(OK, rv);
1310 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381311}
1312
[email protected]23e482282013-06-14 16:08:021313TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381314 HttpRequestInfo request;
1315 request.method = "POST";
1316 request.url = GURL("http://www.foo.com/");
1317 request.load_flags = 0;
1318
danakj1fd259a02016-04-16 03:17:091319 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1320 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411321 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271322
[email protected]ee9410e72010-01-07 01:42:381323 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061324 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381325 };
[email protected]31a2bfe2010-02-09 08:03:391326 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071327 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381328
[email protected]49639fa2011-12-20 23:22:411329 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381330
[email protected]49639fa2011-12-20 23:22:411331 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381332 EXPECT_EQ(ERR_IO_PENDING, rv);
1333
1334 rv = callback.WaitForResult();
1335 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1336}
1337
[email protected]23e482282013-06-14 16:08:021338void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511339 const MockWrite* write_failure,
1340 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421341 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521342 request.method = "GET";
1343 request.url = GURL("http://www.foo.com/");
1344 request.load_flags = 0;
1345
vishal.b62985ca92015-04-17 08:45:511346 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071347 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091348 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271349
[email protected]202965992011-12-07 23:04:511350 // Written data for successfully sending both requests.
1351 MockWrite data1_writes[] = {
1352 MockWrite("GET / HTTP/1.1\r\n"
1353 "Host: www.foo.com\r\n"
1354 "Connection: keep-alive\r\n\r\n"),
1355 MockWrite("GET / HTTP/1.1\r\n"
1356 "Host: www.foo.com\r\n"
1357 "Connection: keep-alive\r\n\r\n")
1358 };
1359
1360 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521361 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351362 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1363 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061364 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521365 };
[email protected]202965992011-12-07 23:04:511366
1367 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491368 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511369 data1_writes[1] = *write_failure;
1370 } else {
1371 ASSERT_TRUE(read_failure);
1372 data1_reads[2] = *read_failure;
1373 }
1374
1375 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1376 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071377 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521378
1379 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351380 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1381 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061382 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521383 };
[email protected]31a2bfe2010-02-09 08:03:391384 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071385 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521386
thestig9d3bb0c2015-01-24 00:49:511387 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521388 "hello", "world"
1389 };
1390
avibf0746c2015-12-09 19:53:141391 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521392 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411393 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521394
danakj1fd259a02016-04-16 03:17:091395 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501396 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521397
[email protected]49639fa2011-12-20 23:22:411398 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421399 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521400
1401 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421402 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521403
[email protected]58e32bb2013-01-21 18:23:251404 LoadTimingInfo load_timing_info;
1405 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1406 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1407 if (i == 0) {
1408 first_socket_log_id = load_timing_info.socket_log_id;
1409 } else {
1410 // The second request should be using a new socket.
1411 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1412 }
1413
[email protected]1c773ea12009-04-28 19:58:421414 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521415 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521416
wezca1070932016-05-26 20:30:521417 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251418 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521419
1420 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571421 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421422 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251423 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521424 }
1425}
[email protected]3d2a59b2008-09-26 19:44:251426
[email protected]a34f61ee2014-03-18 20:59:491427void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1428 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101429 const MockRead* read_failure,
1430 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491431 HttpRequestInfo request;
1432 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101433 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491434 request.load_flags = 0;
1435
vishal.b62985ca92015-04-17 08:45:511436 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491437 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091438 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491439
[email protected]09356c652014-03-25 15:36:101440 SSLSocketDataProvider ssl1(ASYNC, OK);
1441 SSLSocketDataProvider ssl2(ASYNC, OK);
1442 if (use_spdy) {
rdsmithebb50aa2015-11-12 03:44:381443 ssl1.SetNextProto(GetProtocol());
1444 ssl2.SetNextProto(GetProtocol());
[email protected]09356c652014-03-25 15:36:101445 }
1446 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1447 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491448
[email protected]09356c652014-03-25 15:36:101449 // SPDY versions of the request and response.
danakj1fd259a02016-04-16 03:17:091450 std::unique_ptr<SpdySerializedFrame> spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491451 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
danakj1fd259a02016-04-16 03:17:091452 std::unique_ptr<SpdySerializedFrame> spdy_response(
[email protected]09356c652014-03-25 15:36:101453 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:091454 std::unique_ptr<SpdySerializedFrame> spdy_data(
[email protected]09356c652014-03-25 15:36:101455 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491456
[email protected]09356c652014-03-25 15:36:101457 // HTTP/1.1 versions of the request and response.
1458 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1459 "Host: www.foo.com\r\n"
1460 "Connection: keep-alive\r\n\r\n";
1461 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1462 const char kHttpData[] = "hello";
1463
1464 std::vector<MockRead> data1_reads;
1465 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491466 if (write_failure) {
1467 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101468 data1_writes.push_back(*write_failure);
1469 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491470 } else {
1471 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101472 if (use_spdy) {
1473 data1_writes.push_back(CreateMockWrite(*spdy_request));
1474 } else {
1475 data1_writes.push_back(MockWrite(kHttpRequest));
1476 }
1477 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491478 }
1479
[email protected]09356c652014-03-25 15:36:101480 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1481 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491482 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1483
[email protected]09356c652014-03-25 15:36:101484 std::vector<MockRead> data2_reads;
1485 std::vector<MockWrite> data2_writes;
1486
1487 if (use_spdy) {
1488 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1489
1490 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1491 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1492 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1493 } else {
1494 data2_writes.push_back(
1495 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1496
1497 data2_reads.push_back(
1498 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1499 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1500 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1501 }
rch8e6c6c42015-05-01 14:05:131502 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1503 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491504 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1505
1506 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591507 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491508 // Wait for the preconnect to complete.
1509 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1510 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101511 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491512
1513 // Make the request.
1514 TestCompletionCallback callback;
1515
danakj1fd259a02016-04-16 03:17:091516 std::unique_ptr<HttpTransaction> trans(
[email protected]a34f61ee2014-03-18 20:59:491517 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1518
1519 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1520 EXPECT_EQ(ERR_IO_PENDING, rv);
1521
1522 rv = callback.WaitForResult();
1523 EXPECT_EQ(OK, rv);
1524
1525 LoadTimingInfo load_timing_info;
1526 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101527 TestLoadTimingNotReused(
1528 load_timing_info,
1529 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491530
1531 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521532 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491533
wezca1070932016-05-26 20:30:521534 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021535 if (response->was_fetched_via_spdy) {
1536 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1537 } else {
1538 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1539 }
[email protected]a34f61ee2014-03-18 20:59:491540
1541 std::string response_data;
1542 rv = ReadTransaction(trans.get(), &response_data);
1543 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101544 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491545}
1546
[email protected]23e482282013-06-14 16:08:021547TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231548 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061549 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511550 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1551}
1552
[email protected]23e482282013-06-14 16:08:021553TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061554 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511555 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251556}
1557
[email protected]23e482282013-06-14 16:08:021558TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061559 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511560 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251561}
1562
[email protected]d58ceea82014-06-04 10:55:541563// Make sure that on a 408 response (Request Timeout), the request is retried,
1564// if the socket was a reused keep alive socket.
1565TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1566 MockRead read_failure(SYNCHRONOUS,
1567 "HTTP/1.1 408 Request Timeout\r\n"
1568 "Connection: Keep-Alive\r\n"
1569 "Content-Length: 6\r\n\r\n"
1570 "Pickle");
1571 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1572}
1573
[email protected]a34f61ee2014-03-18 20:59:491574TEST_P(HttpNetworkTransactionTest,
1575 PreconnectErrorNotConnectedOnWrite) {
1576 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101577 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491578}
1579
1580TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1581 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101582 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491583}
1584
1585TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1586 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101587 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1588}
1589
1590TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1591 MockRead read_failure(ASYNC, OK); // EOF
1592 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1593}
1594
[email protected]d58ceea82014-06-04 10:55:541595// Make sure that on a 408 response (Request Timeout), the request is retried,
1596// if the socket was a preconnected (UNUSED_IDLE) socket.
1597TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1598 MockRead read_failure(SYNCHRONOUS,
1599 "HTTP/1.1 408 Request Timeout\r\n"
1600 "Connection: Keep-Alive\r\n"
1601 "Content-Length: 6\r\n\r\n"
1602 "Pickle");
1603 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1604 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1605}
1606
[email protected]09356c652014-03-25 15:36:101607TEST_P(HttpNetworkTransactionTest,
1608 SpdyPreconnectErrorNotConnectedOnWrite) {
1609 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1610 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1611}
1612
1613TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1614 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1615 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1616}
1617
1618TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1619 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1620 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1621}
1622
1623TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1624 MockRead read_failure(ASYNC, OK); // EOF
1625 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491626}
1627
[email protected]23e482282013-06-14 16:08:021628TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421629 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251630 request.method = "GET";
bncce36dca22015-04-21 22:11:231631 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251632 request.load_flags = 0;
1633
danakj1fd259a02016-04-16 03:17:091634 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1635 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411636 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271637
[email protected]3d2a59b2008-09-26 19:44:251638 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061639 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351640 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1641 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061642 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251643 };
[email protected]31a2bfe2010-02-09 08:03:391644 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071645 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251646
[email protected]49639fa2011-12-20 23:22:411647 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251648
[email protected]49639fa2011-12-20 23:22:411649 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421650 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251651
1652 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421653 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:591654
1655 IPEndPoint endpoint;
1656 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
1657 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251658}
1659
1660// What do various browsers do when the server closes a non-keepalive
1661// connection without sending any response header or body?
1662//
1663// IE7: error page
1664// Safari 3.1.2 (Windows): error page
1665// Firefox 3.0.1: blank page
1666// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421667// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1668// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021669TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251670 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061671 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351672 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1673 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061674 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251675 };
[email protected]31a2bfe2010-02-09 08:03:391676 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1677 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421678 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251679}
[email protected]038e9a32008-10-08 22:40:161680
[email protected]1826a402014-01-08 15:40:481681// Test that network access can be deferred and resumed.
1682TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1683 HttpRequestInfo request;
1684 request.method = "GET";
bncce36dca22015-04-21 22:11:231685 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481686 request.load_flags = 0;
1687
danakj1fd259a02016-04-16 03:17:091688 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1689 std::unique_ptr<HttpTransaction> trans(
[email protected]1826a402014-01-08 15:40:481690 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1691
1692 // Defer on OnBeforeNetworkStart.
1693 BeforeNetworkStartHandler net_start_handler(true); // defer
1694 trans->SetBeforeNetworkStartCallback(
1695 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1696 base::Unretained(&net_start_handler)));
1697
1698 MockRead data_reads[] = {
1699 MockRead("HTTP/1.0 200 OK\r\n"),
1700 MockRead("Content-Length: 5\r\n\r\n"),
1701 MockRead("hello"),
1702 MockRead(SYNCHRONOUS, 0),
1703 };
1704 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1705 session_deps_.socket_factory->AddSocketDataProvider(&data);
1706
1707 TestCompletionCallback callback;
1708
1709 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1710 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:551711 base::RunLoop().RunUntilIdle();
[email protected]1826a402014-01-08 15:40:481712
1713 // Should have deferred for network start.
1714 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1715 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481716
1717 trans->ResumeNetworkStart();
1718 rv = callback.WaitForResult();
1719 EXPECT_EQ(OK, rv);
wezca1070932016-05-26 20:30:521720 EXPECT_TRUE(trans->GetResponseInfo());
[email protected]1826a402014-01-08 15:40:481721
1722 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1723 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1724 if (rv == ERR_IO_PENDING)
1725 rv = callback.WaitForResult();
1726 EXPECT_EQ(5, rv);
1727 trans.reset();
1728}
1729
1730// Test that network use can be deferred and canceled.
1731TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1732 HttpRequestInfo request;
1733 request.method = "GET";
bncce36dca22015-04-21 22:11:231734 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481735 request.load_flags = 0;
1736
danakj1fd259a02016-04-16 03:17:091737 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1738 std::unique_ptr<HttpTransaction> trans(
[email protected]1826a402014-01-08 15:40:481739 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1740
1741 // Defer on OnBeforeNetworkStart.
1742 BeforeNetworkStartHandler net_start_handler(true); // defer
1743 trans->SetBeforeNetworkStartCallback(
1744 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1745 base::Unretained(&net_start_handler)));
1746
1747 TestCompletionCallback callback;
1748
1749 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1750 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:551751 base::RunLoop().RunUntilIdle();
[email protected]1826a402014-01-08 15:40:481752
1753 // Should have deferred for network start.
1754 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1755 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481756}
1757
[email protected]7a5378b2012-11-04 03:25:171758// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1759// tests. There was a bug causing HttpNetworkTransaction to hang in the
1760// destructor in such situations.
1761// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021762TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171763 HttpRequestInfo request;
1764 request.method = "GET";
bncce36dca22015-04-21 22:11:231765 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171766 request.load_flags = 0;
1767
danakj1fd259a02016-04-16 03:17:091768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1769 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171771
1772 MockRead data_reads[] = {
1773 MockRead("HTTP/1.0 200 OK\r\n"),
1774 MockRead("Connection: keep-alive\r\n"),
1775 MockRead("Content-Length: 100\r\n\r\n"),
1776 MockRead("hello"),
1777 MockRead(SYNCHRONOUS, 0),
1778 };
1779 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071780 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171781
1782 TestCompletionCallback callback;
1783
1784 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1785 EXPECT_EQ(ERR_IO_PENDING, rv);
1786
1787 rv = callback.WaitForResult();
1788 EXPECT_EQ(OK, rv);
1789
1790 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501791 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171792 if (rv == ERR_IO_PENDING)
1793 rv = callback.WaitForResult();
1794 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501795 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171796 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1797
1798 trans.reset();
fdoray92e35a72016-06-10 15:54:551799 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171800 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1801}
1802
[email protected]23e482282013-06-14 16:08:021803TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171804 HttpRequestInfo request;
1805 request.method = "GET";
bncce36dca22015-04-21 22:11:231806 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171807 request.load_flags = 0;
1808
danakj1fd259a02016-04-16 03:17:091809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1810 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501811 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171812
1813 MockRead data_reads[] = {
1814 MockRead("HTTP/1.0 200 OK\r\n"),
1815 MockRead("Connection: keep-alive\r\n"),
1816 MockRead("Content-Length: 100\r\n\r\n"),
1817 MockRead(SYNCHRONOUS, 0),
1818 };
1819 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071820 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171821
1822 TestCompletionCallback callback;
1823
1824 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1825 EXPECT_EQ(ERR_IO_PENDING, rv);
1826
1827 rv = callback.WaitForResult();
1828 EXPECT_EQ(OK, rv);
1829
1830 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501831 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171832 if (rv == ERR_IO_PENDING)
1833 rv = callback.WaitForResult();
1834 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1835
1836 trans.reset();
fdoray92e35a72016-06-10 15:54:551837 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171838 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1839}
1840
[email protected]0b0bf032010-09-21 18:08:501841// Test that we correctly reuse a keep-alive connection after not explicitly
1842// reading the body.
[email protected]23e482282013-06-14 16:08:021843TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131844 HttpRequestInfo request;
1845 request.method = "GET";
1846 request.url = GURL("http://www.foo.com/");
1847 request.load_flags = 0;
1848
vishal.b62985ca92015-04-17 08:45:511849 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071850 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091851 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271852
mmenkecc2298e2015-12-07 18:20:181853 const char* request_data =
1854 "GET / HTTP/1.1\r\n"
1855 "Host: www.foo.com\r\n"
1856 "Connection: keep-alive\r\n\r\n";
1857 MockWrite data_writes[] = {
1858 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1859 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1860 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1861 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1862 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1863 };
1864
[email protected]0b0bf032010-09-21 18:08:501865 // Note that because all these reads happen in the same
1866 // StaticSocketDataProvider, it shows that the same socket is being reused for
1867 // all transactions.
mmenkecc2298e2015-12-07 18:20:181868 MockRead data_reads[] = {
1869 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1870 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1871 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1872 MockRead(ASYNC, 7,
1873 "HTTP/1.1 302 Found\r\n"
1874 "Content-Length: 0\r\n\r\n"),
1875 MockRead(ASYNC, 9,
1876 "HTTP/1.1 302 Found\r\n"
1877 "Content-Length: 5\r\n\r\n"
1878 "hello"),
1879 MockRead(ASYNC, 11,
1880 "HTTP/1.1 301 Moved Permanently\r\n"
1881 "Content-Length: 0\r\n\r\n"),
1882 MockRead(ASYNC, 13,
1883 "HTTP/1.1 301 Moved Permanently\r\n"
1884 "Content-Length: 5\r\n\r\n"
1885 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131886
mmenkecc2298e2015-12-07 18:20:181887 // In the next two rounds, IsConnectedAndIdle returns false, due to
1888 // the set_busy_before_sync_reads(true) call, while the
1889 // HttpNetworkTransaction is being shut down, but the socket is still
1890 // reuseable. See http://crbug.com/544255.
1891 MockRead(ASYNC, 15,
1892 "HTTP/1.1 200 Hunky-Dory\r\n"
1893 "Content-Length: 5\r\n\r\n"),
1894 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131895
mmenkecc2298e2015-12-07 18:20:181896 MockRead(ASYNC, 18,
1897 "HTTP/1.1 200 Hunky-Dory\r\n"
1898 "Content-Length: 5\r\n\r\n"
1899 "he"),
1900 MockRead(SYNCHRONOUS, 19, "llo"),
1901
1902 // The body of the final request is actually read.
1903 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1904 MockRead(ASYNC, 22, "hello"),
1905 };
1906 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1907 arraysize(data_writes));
1908 data.set_busy_before_sync_reads(true);
1909 session_deps_.socket_factory->AddSocketDataProvider(&data);
1910
1911 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501912 std::string response_lines[kNumUnreadBodies];
1913
avibf0746c2015-12-09 19:53:141914 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181915 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411916 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131917
danakj1fd259a02016-04-16 03:17:091918 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501919 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131920
[email protected]49639fa2011-12-20 23:22:411921 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
mmenkecc2298e2015-12-07 18:20:181922 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]fc31d6a42010-06-24 18:05:131923
[email protected]58e32bb2013-01-21 18:23:251924 LoadTimingInfo load_timing_info;
1925 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1926 if (i == 0) {
1927 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1928 first_socket_log_id = load_timing_info.socket_log_id;
1929 } else {
1930 TestLoadTimingReused(load_timing_info);
1931 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1932 }
1933
[email protected]fc31d6a42010-06-24 18:05:131934 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181935 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131936
mmenkecc2298e2015-12-07 18:20:181937 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501938 response_lines[i] = response->headers->GetStatusLine();
1939
mmenkecc2298e2015-12-07 18:20:181940 // Delete the transaction without reading the response bodies. Then spin
1941 // the message loop, so the response bodies are drained.
1942 trans.reset();
1943 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131944 }
[email protected]0b0bf032010-09-21 18:08:501945
1946 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181947 "HTTP/1.1 204 No Content",
1948 "HTTP/1.1 205 Reset Content",
1949 "HTTP/1.1 304 Not Modified",
1950 "HTTP/1.1 302 Found",
1951 "HTTP/1.1 302 Found",
1952 "HTTP/1.1 301 Moved Permanently",
1953 "HTTP/1.1 301 Moved Permanently",
1954 "HTTP/1.1 200 Hunky-Dory",
1955 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:501956 };
1957
mostynb91e0da982015-01-20 19:17:271958 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1959 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501960
1961 for (int i = 0; i < kNumUnreadBodies; ++i)
1962 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1963
[email protected]49639fa2011-12-20 23:22:411964 TestCompletionCallback callback;
danakj1fd259a02016-04-16 03:17:091965 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501966 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411967 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
mmenkecc2298e2015-12-07 18:20:181968 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]0b0bf032010-09-21 18:08:501969 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181970 ASSERT_TRUE(response);
1971 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501972 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1973 std::string response_data;
1974 rv = ReadTransaction(trans.get(), &response_data);
1975 EXPECT_EQ(OK, rv);
1976 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131977}
1978
mmenke5f94fda2016-06-02 20:54:131979// Sockets that receive extra data after a response is complete should not be
1980// reused.
1981TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
1982 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1983 MockWrite data_writes1[] = {
1984 MockWrite("HEAD / HTTP/1.1\r\n"
1985 "Host: www.borked.com\r\n"
1986 "Connection: keep-alive\r\n\r\n"),
1987 };
1988
1989 MockRead data_reads1[] = {
1990 MockRead("HTTP/1.1 200 OK\r\n"
1991 "Connection: keep-alive\r\n"
1992 "Content-Length: 22\r\n\r\n"
1993 "This server is borked."),
1994 };
1995
1996 MockWrite data_writes2[] = {
1997 MockWrite("GET /foo HTTP/1.1\r\n"
1998 "Host: www.borked.com\r\n"
1999 "Connection: keep-alive\r\n\r\n"),
2000 };
2001
2002 MockRead data_reads2[] = {
2003 MockRead("HTTP/1.1 200 OK\r\n"
2004 "Content-Length: 3\r\n\r\n"
2005 "foo"),
2006 };
2007 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2008 data_writes1, arraysize(data_writes1));
2009 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2010 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2011 data_writes2, arraysize(data_writes2));
2012 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2013
2014 TestCompletionCallback callback;
2015 HttpRequestInfo request1;
2016 request1.method = "HEAD";
2017 request1.url = GURL("http://www.borked.com/");
2018
2019 std::unique_ptr<HttpTransaction> trans1(
2020 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2021 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2022 EXPECT_EQ(OK, callback.GetResult(rv));
2023
2024 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2025 ASSERT_TRUE(response1);
2026 ASSERT_TRUE(response1->headers);
2027 EXPECT_EQ(200, response1->headers->response_code());
2028 EXPECT_TRUE(response1->headers->IsKeepAlive());
2029
2030 std::string response_data1;
2031 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
2032 EXPECT_EQ("", response_data1);
2033 // Deleting the transaction attempts to release the socket back into the
2034 // socket pool.
2035 trans1.reset();
2036
2037 HttpRequestInfo request2;
2038 request2.method = "GET";
2039 request2.url = GURL("http://www.borked.com/foo");
2040
2041 std::unique_ptr<HttpTransaction> trans2(
2042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2043 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
2044 EXPECT_EQ(OK, callback.GetResult(rv));
2045
2046 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2047 ASSERT_TRUE(response2);
2048 ASSERT_TRUE(response2->headers);
2049 EXPECT_EQ(200, response2->headers->response_code());
2050
2051 std::string response_data2;
2052 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2));
2053 EXPECT_EQ("foo", response_data2);
2054}
2055
2056TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
2057 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2058 MockWrite data_writes1[] = {
2059 MockWrite("GET / HTTP/1.1\r\n"
2060 "Host: www.borked.com\r\n"
2061 "Connection: keep-alive\r\n\r\n"),
2062 };
2063
2064 MockRead data_reads1[] = {
2065 MockRead("HTTP/1.1 200 OK\r\n"
2066 "Connection: keep-alive\r\n"
2067 "Content-Length: 22\r\n\r\n"
2068 "This server is borked."
2069 "Bonus data!"),
2070 };
2071
2072 MockWrite data_writes2[] = {
2073 MockWrite("GET /foo HTTP/1.1\r\n"
2074 "Host: www.borked.com\r\n"
2075 "Connection: keep-alive\r\n\r\n"),
2076 };
2077
2078 MockRead data_reads2[] = {
2079 MockRead("HTTP/1.1 200 OK\r\n"
2080 "Content-Length: 3\r\n\r\n"
2081 "foo"),
2082 };
2083 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2084 data_writes1, arraysize(data_writes1));
2085 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2086 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2087 data_writes2, arraysize(data_writes2));
2088 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2089
2090 TestCompletionCallback callback;
2091 HttpRequestInfo request1;
2092 request1.method = "GET";
2093 request1.url = GURL("http://www.borked.com/");
2094
2095 std::unique_ptr<HttpTransaction> trans1(
2096 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2097 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2098 EXPECT_EQ(OK, callback.GetResult(rv));
2099
2100 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2101 ASSERT_TRUE(response1);
2102 ASSERT_TRUE(response1->headers);
2103 EXPECT_EQ(200, response1->headers->response_code());
2104 EXPECT_TRUE(response1->headers->IsKeepAlive());
2105
2106 std::string response_data1;
2107 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
2108 EXPECT_EQ("This server is borked.", response_data1);
2109 // Deleting the transaction attempts to release the socket back into the
2110 // socket pool.
2111 trans1.reset();
2112
2113 HttpRequestInfo request2;
2114 request2.method = "GET";
2115 request2.url = GURL("http://www.borked.com/foo");
2116
2117 std::unique_ptr<HttpTransaction> trans2(
2118 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2119 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
2120 EXPECT_EQ(OK, callback.GetResult(rv));
2121
2122 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2123 ASSERT_TRUE(response2);
2124 ASSERT_TRUE(response2->headers);
2125 EXPECT_EQ(200, response2->headers->response_code());
2126
2127 std::string response_data2;
2128 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2));
2129 EXPECT_EQ("foo", response_data2);
2130}
2131
2132TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
2133 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2134 MockWrite data_writes1[] = {
2135 MockWrite("GET / HTTP/1.1\r\n"
2136 "Host: www.borked.com\r\n"
2137 "Connection: keep-alive\r\n\r\n"),
2138 };
2139
2140 MockRead data_reads1[] = {
2141 MockRead("HTTP/1.1 200 OK\r\n"
2142 "Connection: keep-alive\r\n"
2143 "Transfer-Encoding: chunked\r\n\r\n"),
2144 MockRead("16\r\nThis server is borked.\r\n"),
2145 MockRead("0\r\n\r\nBonus data!"),
2146 };
2147
2148 MockWrite data_writes2[] = {
2149 MockWrite("GET /foo HTTP/1.1\r\n"
2150 "Host: www.borked.com\r\n"
2151 "Connection: keep-alive\r\n\r\n"),
2152 };
2153
2154 MockRead data_reads2[] = {
2155 MockRead("HTTP/1.1 200 OK\r\n"
2156 "Content-Length: 3\r\n\r\n"
2157 "foo"),
2158 };
2159 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2160 data_writes1, arraysize(data_writes1));
2161 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2162 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2163 data_writes2, arraysize(data_writes2));
2164 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2165
2166 TestCompletionCallback callback;
2167 HttpRequestInfo request1;
2168 request1.method = "GET";
2169 request1.url = GURL("http://www.borked.com/");
2170
2171 std::unique_ptr<HttpTransaction> trans1(
2172 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2173 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2174 EXPECT_EQ(OK, callback.GetResult(rv));
2175
2176 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2177 ASSERT_TRUE(response1);
2178 ASSERT_TRUE(response1->headers);
2179 EXPECT_EQ(200, response1->headers->response_code());
2180 EXPECT_TRUE(response1->headers->IsKeepAlive());
2181
2182 std::string response_data1;
2183 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
2184 EXPECT_EQ("This server is borked.", response_data1);
2185 // Deleting the transaction attempts to release the socket back into the
2186 // socket pool.
2187 trans1.reset();
2188
2189 HttpRequestInfo request2;
2190 request2.method = "GET";
2191 request2.url = GURL("http://www.borked.com/foo");
2192
2193 std::unique_ptr<HttpTransaction> trans2(
2194 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2195 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
2196 EXPECT_EQ(OK, callback.GetResult(rv));
2197
2198 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2199 ASSERT_TRUE(response2);
2200 ASSERT_TRUE(response2->headers);
2201 EXPECT_EQ(200, response2->headers->response_code());
2202
2203 std::string response_data2;
2204 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2));
2205 EXPECT_EQ("foo", response_data2);
2206}
2207
2208// This is a little different from the others - it tests the case that the
2209// HttpStreamParser doesn't know if there's extra data on a socket or not when
2210// the HttpNetworkTransaction is torn down, because the response body hasn't
2211// been read from yet, but the request goes through the HttpResponseBodyDrainer.
2212TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
2213 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2214 MockWrite data_writes1[] = {
2215 MockWrite("GET / HTTP/1.1\r\n"
2216 "Host: www.borked.com\r\n"
2217 "Connection: keep-alive\r\n\r\n"),
2218 };
2219
2220 MockRead data_reads1[] = {
2221 MockRead("HTTP/1.1 200 OK\r\n"
2222 "Connection: keep-alive\r\n"
2223 "Transfer-Encoding: chunked\r\n\r\n"),
2224 MockRead("16\r\nThis server is borked.\r\n"),
2225 MockRead("0\r\n\r\nBonus data!"),
2226 };
2227 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2228 data_writes1, arraysize(data_writes1));
2229 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2230
2231 TestCompletionCallback callback;
2232 HttpRequestInfo request1;
2233 request1.method = "GET";
2234 request1.url = GURL("http://www.borked.com/");
2235
2236 std::unique_ptr<HttpTransaction> trans1(
2237 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2238 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2239 EXPECT_EQ(OK, callback.GetResult(rv));
2240
2241 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2242 ASSERT_TRUE(response1);
2243 ASSERT_TRUE(response1->headers);
2244 EXPECT_EQ(200, response1->headers->response_code());
2245 EXPECT_TRUE(response1->headers->IsKeepAlive());
2246
2247 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2248 // response body.
2249 trans1.reset();
2250
2251 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2252 // socket can't be reused, rather than returning it to the socket pool.
2253 base::RunLoop().RunUntilIdle();
2254
2255 // There should be no idle sockets in the pool.
2256 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2257}
2258
[email protected]038e9a32008-10-08 22:40:162259// Test the request-challenge-retry sequence for basic auth.
2260// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:022261TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422262 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162263 request.method = "GET";
bncce36dca22015-04-21 22:11:232264 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162265 request.load_flags = 0;
2266
vishal.b62985ca92015-04-17 08:45:512267 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072268 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092269 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2270 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412271 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272272
[email protected]f9ee6b52008-11-08 06:46:232273 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232274 MockWrite(
2275 "GET / HTTP/1.1\r\n"
2276 "Host: www.example.org\r\n"
2277 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232278 };
2279
[email protected]038e9a32008-10-08 22:40:162280 MockRead data_reads1[] = {
2281 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2282 // Give a couple authenticate options (only the middle one is actually
2283 // supported).
[email protected]22927ad2009-09-21 19:56:192284 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162285 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2286 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2287 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2288 // Large content-length -- won't matter, as connection will be reset.
2289 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062290 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162291 };
2292
2293 // After calling trans->RestartWithAuth(), this is the request we should
2294 // be issuing -- the final header line contains the credentials.
2295 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232296 MockWrite(
2297 "GET / HTTP/1.1\r\n"
2298 "Host: www.example.org\r\n"
2299 "Connection: keep-alive\r\n"
2300 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162301 };
2302
2303 // Lastly, the server responds with the actual content.
2304 MockRead data_reads2[] = {
2305 MockRead("HTTP/1.0 200 OK\r\n"),
2306 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2307 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062308 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162309 };
2310
[email protected]31a2bfe2010-02-09 08:03:392311 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2312 data_writes1, arraysize(data_writes1));
2313 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2314 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072315 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2316 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162317
[email protected]49639fa2011-12-20 23:22:412318 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162319
[email protected]49639fa2011-12-20 23:22:412320 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422321 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162322
2323 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422324 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162325
[email protected]58e32bb2013-01-21 18:23:252326 LoadTimingInfo load_timing_info1;
2327 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2328 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2329
sclittlefb249892015-09-10 21:33:222330 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2331 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2332 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:192333 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2334
[email protected]1c773ea12009-04-28 19:58:422335 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522336 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042337 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162338
[email protected]49639fa2011-12-20 23:22:412339 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162340
[email protected]49639fa2011-12-20 23:22:412341 rv = trans->RestartWithAuth(
2342 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422343 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162344
2345 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422346 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162347
[email protected]58e32bb2013-01-21 18:23:252348 LoadTimingInfo load_timing_info2;
2349 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2350 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2351 // The load timing after restart should have a new socket ID, and times after
2352 // those of the first load timing.
2353 EXPECT_LE(load_timing_info1.receive_headers_end,
2354 load_timing_info2.connect_timing.connect_start);
2355 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2356
sclittlefb249892015-09-10 21:33:222357 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2358 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2359 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
[email protected]b8015c42013-12-24 15:18:192360 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2361
[email protected]038e9a32008-10-08 22:40:162362 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522363 ASSERT_TRUE(response);
2364 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162365 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162366}
2367
ttuttled9dbc652015-09-29 20:00:592368// Test the request-challenge-retry sequence for basic auth.
2369// (basic auth is the easiest to mock, because it has no randomness).
2370TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
2371 HttpRequestInfo request;
2372 request.method = "GET";
2373 request.url = GURL("http://www.example.org/");
2374 request.load_flags = 0;
2375
2376 TestNetLog log;
2377 MockHostResolver* resolver = new MockHostResolver();
2378 session_deps_.net_log = &log;
2379 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092380 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
2381 std::unique_ptr<HttpTransaction> trans(
ttuttled9dbc652015-09-29 20:00:592382 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2383
2384 resolver->rules()->ClearRules();
2385 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2386
2387 MockWrite data_writes1[] = {
2388 MockWrite("GET / HTTP/1.1\r\n"
2389 "Host: www.example.org\r\n"
2390 "Connection: keep-alive\r\n\r\n"),
2391 };
2392
2393 MockRead data_reads1[] = {
2394 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2395 // Give a couple authenticate options (only the middle one is actually
2396 // supported).
2397 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2398 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2399 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2400 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2401 // Large content-length -- won't matter, as connection will be reset.
2402 MockRead("Content-Length: 10000\r\n\r\n"),
2403 MockRead(SYNCHRONOUS, ERR_FAILED),
2404 };
2405
2406 // After calling trans->RestartWithAuth(), this is the request we should
2407 // be issuing -- the final header line contains the credentials.
2408 MockWrite data_writes2[] = {
2409 MockWrite("GET / HTTP/1.1\r\n"
2410 "Host: www.example.org\r\n"
2411 "Connection: keep-alive\r\n"
2412 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2413 };
2414
2415 // Lastly, the server responds with the actual content.
2416 MockRead data_reads2[] = {
2417 MockRead("HTTP/1.0 200 OK\r\n"),
2418 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2419 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2420 };
2421
2422 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2423 data_writes1, arraysize(data_writes1));
2424 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2425 data_writes2, arraysize(data_writes2));
2426 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2427 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2428
2429 TestCompletionCallback callback1;
2430
2431 EXPECT_EQ(OK, callback1.GetResult(trans->Start(&request, callback1.callback(),
2432 BoundNetLog())));
2433
2434 LoadTimingInfo load_timing_info1;
2435 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2436 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2437
2438 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2439 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2440 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
2441 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2442
2443 const HttpResponseInfo* response = trans->GetResponseInfo();
2444 ASSERT_TRUE(response);
2445 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2446
2447 IPEndPoint endpoint;
2448 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2449 ASSERT_FALSE(endpoint.address().empty());
2450 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2451
2452 resolver->rules()->ClearRules();
2453 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2454
2455 TestCompletionCallback callback2;
2456
2457 EXPECT_EQ(OK, callback2.GetResult(trans->RestartWithAuth(
2458 AuthCredentials(kFoo, kBar), callback2.callback())));
2459
2460 LoadTimingInfo load_timing_info2;
2461 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2462 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2463 // The load timing after restart should have a new socket ID, and times after
2464 // those of the first load timing.
2465 EXPECT_LE(load_timing_info1.receive_headers_end,
2466 load_timing_info2.connect_timing.connect_start);
2467 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2468
2469 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2470 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2471 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
2472 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2473
2474 response = trans->GetResponseInfo();
2475 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522476 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592477 EXPECT_EQ(100, response->headers->GetContentLength());
2478
2479 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2480 ASSERT_FALSE(endpoint.address().empty());
2481 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2482}
2483
[email protected]23e482282013-06-14 16:08:022484TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462485 HttpRequestInfo request;
2486 request.method = "GET";
bncce36dca22015-04-21 22:11:232487 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292488 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462489
danakj1fd259a02016-04-16 03:17:092490 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2491 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412492 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272493
[email protected]861fcd52009-08-26 02:33:462494 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232495 MockWrite(
2496 "GET / HTTP/1.1\r\n"
2497 "Host: www.example.org\r\n"
2498 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462499 };
2500
2501 MockRead data_reads[] = {
2502 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2503 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2504 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2505 // Large content-length -- won't matter, as connection will be reset.
2506 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062507 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462508 };
2509
[email protected]31a2bfe2010-02-09 08:03:392510 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2511 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072512 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412513 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462514
[email protected]49639fa2011-12-20 23:22:412515 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462516 EXPECT_EQ(ERR_IO_PENDING, rv);
2517
2518 rv = callback.WaitForResult();
2519 EXPECT_EQ(0, rv);
2520
sclittlefb249892015-09-10 21:33:222521 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2522 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2523 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
[email protected]b8015c42013-12-24 15:18:192524 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2525
[email protected]861fcd52009-08-26 02:33:462526 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522527 ASSERT_TRUE(response);
2528 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462529}
2530
[email protected]2d2697f92009-02-18 21:00:322531// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2532// connection.
[email protected]23e482282013-06-14 16:08:022533TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182534 // On the second pass, the body read of the auth challenge is synchronous, so
2535 // IsConnectedAndIdle returns false. The socket should still be drained and
2536 // reused. See http://crbug.com/544255.
2537 for (int i = 0; i < 2; ++i) {
2538 HttpRequestInfo request;
2539 request.method = "GET";
2540 request.url = GURL("http://www.example.org/");
2541 request.load_flags = 0;
[email protected]2d2697f92009-02-18 21:00:322542
mmenkecc2298e2015-12-07 18:20:182543 TestNetLog log;
2544 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092545 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272546
mmenkecc2298e2015-12-07 18:20:182547 MockWrite data_writes[] = {
2548 MockWrite(ASYNC, 0,
2549 "GET / HTTP/1.1\r\n"
2550 "Host: www.example.org\r\n"
2551 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322552
mmenkecc2298e2015-12-07 18:20:182553 // After calling trans->RestartWithAuth(), this is the request we should
2554 // be issuing -- the final header line contains the credentials.
2555 MockWrite(ASYNC, 6,
2556 "GET / HTTP/1.1\r\n"
2557 "Host: www.example.org\r\n"
2558 "Connection: keep-alive\r\n"
2559 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2560 };
[email protected]2d2697f92009-02-18 21:00:322561
mmenkecc2298e2015-12-07 18:20:182562 MockRead data_reads[] = {
2563 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2564 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2565 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2566 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2567 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322568
mmenkecc2298e2015-12-07 18:20:182569 // Lastly, the server responds with the actual content.
2570 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2571 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2572 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2573 MockRead(ASYNC, 10, "Hello"),
2574 };
[email protected]2d2697f92009-02-18 21:00:322575
mmenkecc2298e2015-12-07 18:20:182576 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2577 arraysize(data_writes));
2578 data.set_busy_before_sync_reads(true);
2579 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462580
mmenkecc2298e2015-12-07 18:20:182581 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322582
danakj1fd259a02016-04-16 03:17:092583 std::unique_ptr<HttpTransaction> trans(
mmenkecc2298e2015-12-07 18:20:182584 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2585 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2586 ASSERT_EQ(OK, callback1.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:322587
mmenkecc2298e2015-12-07 18:20:182588 LoadTimingInfo load_timing_info1;
2589 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2590 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322591
mmenkecc2298e2015-12-07 18:20:182592 const HttpResponseInfo* response = trans->GetResponseInfo();
2593 ASSERT_TRUE(response);
2594 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322595
mmenkecc2298e2015-12-07 18:20:182596 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252597
mmenkecc2298e2015-12-07 18:20:182598 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
2599 callback2.callback());
2600 ASSERT_EQ(OK, callback2.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:322601
mmenkecc2298e2015-12-07 18:20:182602 LoadTimingInfo load_timing_info2;
2603 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2604 TestLoadTimingReused(load_timing_info2);
2605 // The load timing after restart should have the same socket ID, and times
2606 // those of the first load timing.
2607 EXPECT_LE(load_timing_info1.receive_headers_end,
2608 load_timing_info2.send_start);
2609 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322610
mmenkecc2298e2015-12-07 18:20:182611 response = trans->GetResponseInfo();
2612 ASSERT_TRUE(response);
2613 EXPECT_FALSE(response->auth_challenge);
2614 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322615
mmenkecc2298e2015-12-07 18:20:182616 std::string response_data;
2617 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]2d2697f92009-02-18 21:00:322618
mmenkecc2298e2015-12-07 18:20:182619 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2620 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2621 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
2622 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2623 }
[email protected]2d2697f92009-02-18 21:00:322624}
2625
2626// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2627// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022628TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422629 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322630 request.method = "GET";
bncce36dca22015-04-21 22:11:232631 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322632 request.load_flags = 0;
2633
danakj1fd259a02016-04-16 03:17:092634 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272635
[email protected]2d2697f92009-02-18 21:00:322636 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232637 MockWrite(
2638 "GET / HTTP/1.1\r\n"
2639 "Host: www.example.org\r\n"
2640 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322641
bncce36dca22015-04-21 22:11:232642 // After calling trans->RestartWithAuth(), this is the request we should
2643 // be issuing -- the final header line contains the credentials.
2644 MockWrite(
2645 "GET / HTTP/1.1\r\n"
2646 "Host: www.example.org\r\n"
2647 "Connection: keep-alive\r\n"
2648 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322649 };
2650
[email protected]2d2697f92009-02-18 21:00:322651 MockRead data_reads1[] = {
2652 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2653 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312654 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322655
2656 // Lastly, the server responds with the actual content.
2657 MockRead("HTTP/1.1 200 OK\r\n"),
2658 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502659 MockRead("Content-Length: 5\r\n\r\n"),
2660 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322661 };
2662
[email protected]2d0a4f92011-05-05 16:38:462663 // An incorrect reconnect would cause this to be read.
2664 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062665 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462666 };
2667
[email protected]31a2bfe2010-02-09 08:03:392668 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2669 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462670 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2671 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072672 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2673 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322674
[email protected]49639fa2011-12-20 23:22:412675 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322676
danakj1fd259a02016-04-16 03:17:092677 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502678 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412679 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422680 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322681
2682 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422683 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322684
[email protected]1c773ea12009-04-28 19:58:422685 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522686 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042687 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322688
[email protected]49639fa2011-12-20 23:22:412689 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322690
[email protected]49639fa2011-12-20 23:22:412691 rv = trans->RestartWithAuth(
2692 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422693 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322694
2695 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422696 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322697
2698 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522699 ASSERT_TRUE(response);
2700 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502701 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322702}
2703
2704// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2705// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022706TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422707 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322708 request.method = "GET";
bncce36dca22015-04-21 22:11:232709 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322710 request.load_flags = 0;
2711
danakj1fd259a02016-04-16 03:17:092712 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272713
[email protected]2d2697f92009-02-18 21:00:322714 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232715 MockWrite(
2716 "GET / HTTP/1.1\r\n"
2717 "Host: www.example.org\r\n"
2718 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322719
bncce36dca22015-04-21 22:11:232720 // After calling trans->RestartWithAuth(), this is the request we should
2721 // be issuing -- the final header line contains the credentials.
2722 MockWrite(
2723 "GET / HTTP/1.1\r\n"
2724 "Host: www.example.org\r\n"
2725 "Connection: keep-alive\r\n"
2726 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322727 };
2728
2729 // Respond with 5 kb of response body.
2730 std::string large_body_string("Unauthorized");
2731 large_body_string.append(5 * 1024, ' ');
2732 large_body_string.append("\r\n");
2733
2734 MockRead data_reads1[] = {
2735 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2736 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2737 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2738 // 5134 = 12 + 5 * 1024 + 2
2739 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062740 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322741
2742 // Lastly, the server responds with the actual content.
2743 MockRead("HTTP/1.1 200 OK\r\n"),
2744 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502745 MockRead("Content-Length: 5\r\n\r\n"),
2746 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322747 };
2748
[email protected]2d0a4f92011-05-05 16:38:462749 // An incorrect reconnect would cause this to be read.
2750 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062751 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462752 };
2753
[email protected]31a2bfe2010-02-09 08:03:392754 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2755 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462756 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2757 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072758 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2759 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322760
[email protected]49639fa2011-12-20 23:22:412761 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322762
danakj1fd259a02016-04-16 03:17:092763 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502764 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412765 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422766 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322767
2768 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422769 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322770
[email protected]1c773ea12009-04-28 19:58:422771 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522772 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042773 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322774
[email protected]49639fa2011-12-20 23:22:412775 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322776
[email protected]49639fa2011-12-20 23:22:412777 rv = trans->RestartWithAuth(
2778 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422779 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322780
2781 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422782 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322783
2784 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522785 ASSERT_TRUE(response);
2786 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502787 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322788}
2789
2790// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312791// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022792TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312793 HttpRequestInfo request;
2794 request.method = "GET";
bncce36dca22015-04-21 22:11:232795 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312796 request.load_flags = 0;
2797
danakj1fd259a02016-04-16 03:17:092798 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272799
[email protected]11203f012009-11-12 23:02:312800 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232801 MockWrite(
2802 "GET / HTTP/1.1\r\n"
2803 "Host: www.example.org\r\n"
2804 "Connection: keep-alive\r\n\r\n"),
2805 // This simulates the seemingly successful write to a closed connection
2806 // if the bug is not fixed.
2807 MockWrite(
2808 "GET / HTTP/1.1\r\n"
2809 "Host: www.example.org\r\n"
2810 "Connection: keep-alive\r\n"
2811 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312812 };
2813
2814 MockRead data_reads1[] = {
2815 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2816 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2817 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2818 MockRead("Content-Length: 14\r\n\r\n"),
2819 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062820 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312821 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062822 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312823 };
2824
2825 // After calling trans->RestartWithAuth(), this is the request we should
2826 // be issuing -- the final header line contains the credentials.
2827 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232828 MockWrite(
2829 "GET / HTTP/1.1\r\n"
2830 "Host: www.example.org\r\n"
2831 "Connection: keep-alive\r\n"
2832 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312833 };
2834
2835 // Lastly, the server responds with the actual content.
2836 MockRead data_reads2[] = {
2837 MockRead("HTTP/1.1 200 OK\r\n"),
2838 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502839 MockRead("Content-Length: 5\r\n\r\n"),
2840 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312841 };
2842
[email protected]31a2bfe2010-02-09 08:03:392843 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2844 data_writes1, arraysize(data_writes1));
2845 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2846 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072847 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2848 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312849
[email protected]49639fa2011-12-20 23:22:412850 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312851
danakj1fd259a02016-04-16 03:17:092852 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502853 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412854 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312855 EXPECT_EQ(ERR_IO_PENDING, rv);
2856
2857 rv = callback1.WaitForResult();
2858 EXPECT_EQ(OK, rv);
2859
2860 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522861 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042862 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312863
[email protected]49639fa2011-12-20 23:22:412864 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312865
[email protected]49639fa2011-12-20 23:22:412866 rv = trans->RestartWithAuth(
2867 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312868 EXPECT_EQ(ERR_IO_PENDING, rv);
2869
2870 rv = callback2.WaitForResult();
2871 EXPECT_EQ(OK, rv);
2872
2873 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522874 ASSERT_TRUE(response);
2875 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502876 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312877}
2878
[email protected]394816e92010-08-03 07:38:592879// Test the request-challenge-retry sequence for basic auth, over a connection
2880// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012881TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2882 HttpRequestInfo request;
2883 request.method = "GET";
bncce36dca22015-04-21 22:11:232884 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012885 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292886 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012887
2888 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032889 session_deps_.proxy_service =
2890 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512891 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012892 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092893 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012894
2895 // Since we have proxy, should try to establish tunnel.
2896 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542897 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172898 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542899 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012900 };
2901
mmenkee71e15332015-10-07 16:39:542902 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012903 // connection.
2904 MockRead data_reads1[] = {
2905 // No credentials.
2906 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2907 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542908 };
ttuttle34f63b52015-03-05 04:33:012909
mmenkee71e15332015-10-07 16:39:542910 // Since the first connection couldn't be reused, need to establish another
2911 // once given credentials.
2912 MockWrite data_writes2[] = {
2913 // After calling trans->RestartWithAuth(), this is the request we should
2914 // be issuing -- the final header line contains the credentials.
2915 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172916 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542917 "Proxy-Connection: keep-alive\r\n"
2918 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2919
2920 MockWrite("GET / HTTP/1.1\r\n"
2921 "Host: www.example.org\r\n"
2922 "Connection: keep-alive\r\n\r\n"),
2923 };
2924
2925 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012926 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2927
2928 MockRead("HTTP/1.1 200 OK\r\n"),
2929 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2930 MockRead("Content-Length: 5\r\n\r\n"),
2931 MockRead(SYNCHRONOUS, "hello"),
2932 };
2933
2934 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2935 data_writes1, arraysize(data_writes1));
2936 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542937 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2938 data_writes2, arraysize(data_writes2));
2939 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012940 SSLSocketDataProvider ssl(ASYNC, OK);
2941 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2942
2943 TestCompletionCallback callback1;
2944
danakj1fd259a02016-04-16 03:17:092945 std::unique_ptr<HttpTransaction> trans(
ttuttle34f63b52015-03-05 04:33:012946 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2947
2948 int rv = trans->Start(&request, callback1.callback(), log.bound());
2949 EXPECT_EQ(ERR_IO_PENDING, rv);
2950
2951 rv = callback1.WaitForResult();
2952 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462953 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012954 log.GetEntries(&entries);
2955 size_t pos = ExpectLogContainsSomewhere(
2956 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2957 NetLog::PHASE_NONE);
2958 ExpectLogContainsSomewhere(
2959 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2960 NetLog::PHASE_NONE);
2961
2962 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522963 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012964 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522965 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012966 EXPECT_EQ(407, response->headers->response_code());
2967 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2968 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2969
2970 LoadTimingInfo load_timing_info;
2971 // CONNECT requests and responses are handled at the connect job level, so
2972 // the transaction does not yet have a connection.
2973 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2974
2975 TestCompletionCallback callback2;
2976
2977 rv =
2978 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2979 EXPECT_EQ(ERR_IO_PENDING, rv);
2980
2981 rv = callback2.WaitForResult();
2982 EXPECT_EQ(OK, rv);
2983
2984 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522985 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012986
2987 EXPECT_TRUE(response->headers->IsKeepAlive());
2988 EXPECT_EQ(200, response->headers->response_code());
2989 EXPECT_EQ(5, response->headers->GetContentLength());
2990 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2991
2992 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:522993 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:012994
2995 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2996 TestLoadTimingNotReusedWithPac(load_timing_info,
2997 CONNECT_TIMING_HAS_SSL_TIMES);
2998
2999 trans.reset();
3000 session->CloseAllConnections();
3001}
3002
3003// Test the request-challenge-retry sequence for basic auth, over a connection
3004// that requires a restart when setting up an SSL tunnel.
3005TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593006 HttpRequestInfo request;
3007 request.method = "GET";
bncce36dca22015-04-21 22:11:233008 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593009 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293010 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593011
[email protected]cb9bf6ca2011-01-28 13:15:273012 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033013 session_deps_.proxy_service =
3014 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513015 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073016 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093017 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273018
[email protected]394816e92010-08-03 07:38:593019 // Since we have proxy, should try to establish tunnel.
3020 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543021 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173022 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543023 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113024 };
3025
mmenkee71e15332015-10-07 16:39:543026 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083027 // connection.
3028 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543029 // No credentials.
3030 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3031 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3032 MockRead("Proxy-Connection: close\r\n\r\n"),
3033 };
mmenkee0b5c882015-08-26 20:29:113034
mmenkee71e15332015-10-07 16:39:543035 MockWrite data_writes2[] = {
3036 // After calling trans->RestartWithAuth(), this is the request we should
3037 // be issuing -- the final header line contains the credentials.
3038 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173039 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543040 "Proxy-Connection: keep-alive\r\n"
3041 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083042
mmenkee71e15332015-10-07 16:39:543043 MockWrite("GET / HTTP/1.1\r\n"
3044 "Host: www.example.org\r\n"
3045 "Connection: keep-alive\r\n\r\n"),
3046 };
3047
3048 MockRead data_reads2[] = {
3049 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3050
3051 MockRead("HTTP/1.1 200 OK\r\n"),
3052 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3053 MockRead("Content-Length: 5\r\n\r\n"),
3054 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593055 };
3056
3057 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3058 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073059 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543060 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3061 data_writes2, arraysize(data_writes2));
3062 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063063 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073064 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593065
[email protected]49639fa2011-12-20 23:22:413066 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593067
danakj1fd259a02016-04-16 03:17:093068 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503069 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503070
[email protected]49639fa2011-12-20 23:22:413071 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:593072 EXPECT_EQ(ERR_IO_PENDING, rv);
3073
3074 rv = callback1.WaitForResult();
3075 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:463076 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403077 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593078 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403079 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:593080 NetLog::PHASE_NONE);
3081 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403082 entries, pos,
[email protected]394816e92010-08-03 07:38:593083 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3084 NetLog::PHASE_NONE);
3085
3086 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523087 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013088 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523089 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593090 EXPECT_EQ(407, response->headers->response_code());
3091 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043092 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593093
[email protected]029c83b62013-01-24 05:28:203094 LoadTimingInfo load_timing_info;
3095 // CONNECT requests and responses are handled at the connect job level, so
3096 // the transaction does not yet have a connection.
3097 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3098
[email protected]49639fa2011-12-20 23:22:413099 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593100
[email protected]49639fa2011-12-20 23:22:413101 rv = trans->RestartWithAuth(
3102 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:593103 EXPECT_EQ(ERR_IO_PENDING, rv);
3104
3105 rv = callback2.WaitForResult();
3106 EXPECT_EQ(OK, rv);
3107
3108 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523109 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593110
3111 EXPECT_TRUE(response->headers->IsKeepAlive());
3112 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503113 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593114 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3115
3116 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523117 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503118
[email protected]029c83b62013-01-24 05:28:203119 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3120 TestLoadTimingNotReusedWithPac(load_timing_info,
3121 CONNECT_TIMING_HAS_SSL_TIMES);
3122
[email protected]0b0bf032010-09-21 18:08:503123 trans.reset();
[email protected]102e27c2011-02-23 01:01:313124 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593125}
3126
[email protected]11203f012009-11-12 23:02:313127// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013128// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
3129TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233130 // On the second pass, the body read of the auth challenge is synchronous, so
3131 // IsConnectedAndIdle returns false. The socket should still be drained and
3132 // reused. See http://crbug.com/544255.
3133 for (int i = 0; i < 2; ++i) {
3134 HttpRequestInfo request;
3135 request.method = "GET";
3136 request.url = GURL("https://www.example.org/");
3137 // Ensure that proxy authentication is attempted even
3138 // when the no authentication data flag is set.
3139 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013140
mmenked39192ee2015-12-09 00:57:233141 // Configure against proxy server "myproxy:70".
3142 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3143 BoundTestNetLog log;
3144 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093145 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013146
danakj1fd259a02016-04-16 03:17:093147 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:233148 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ttuttle34f63b52015-03-05 04:33:013149
mmenked39192ee2015-12-09 00:57:233150 // Since we have proxy, should try to establish tunnel.
3151 MockWrite data_writes1[] = {
3152 MockWrite(ASYNC, 0,
3153 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3154 "Host: www.example.org:443\r\n"
3155 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013156
mmenked39192ee2015-12-09 00:57:233157 // After calling trans->RestartWithAuth(), this is the request we should
3158 // be issuing -- the final header line contains the credentials.
3159 MockWrite(ASYNC, 3,
3160 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3161 "Host: www.example.org:443\r\n"
3162 "Proxy-Connection: keep-alive\r\n"
3163 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3164 };
ttuttle34f63b52015-03-05 04:33:013165
mmenked39192ee2015-12-09 00:57:233166 // The proxy responds to the connect with a 407, using a persistent
3167 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3168 MockRead data_reads1[] = {
3169 // No credentials.
3170 MockRead(ASYNC, 1,
3171 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3172 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3173 "Proxy-Connection: keep-alive\r\n"
3174 "Content-Length: 10\r\n\r\n"),
3175 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013176
mmenked39192ee2015-12-09 00:57:233177 // Wrong credentials (wrong password).
3178 MockRead(ASYNC, 4,
3179 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3180 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3181 "Proxy-Connection: keep-alive\r\n"
3182 "Content-Length: 10\r\n\r\n"),
3183 // No response body because the test stops reading here.
3184 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3185 };
ttuttle34f63b52015-03-05 04:33:013186
mmenked39192ee2015-12-09 00:57:233187 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3188 arraysize(data_writes1));
3189 data1.set_busy_before_sync_reads(true);
3190 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013191
mmenked39192ee2015-12-09 00:57:233192 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013193
mmenked39192ee2015-12-09 00:57:233194 int rv = trans->Start(&request, callback1.callback(), log.bound());
3195 EXPECT_EQ(OK, callback1.GetResult(rv));
ttuttle34f63b52015-03-05 04:33:013196
mmenked39192ee2015-12-09 00:57:233197 TestNetLogEntry::List entries;
3198 log.GetEntries(&entries);
3199 size_t pos = ExpectLogContainsSomewhere(
3200 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3201 NetLog::PHASE_NONE);
3202 ExpectLogContainsSomewhere(
3203 entries, pos,
3204 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3205 NetLog::PHASE_NONE);
ttuttle34f63b52015-03-05 04:33:013206
mmenked39192ee2015-12-09 00:57:233207 const HttpResponseInfo* response = trans->GetResponseInfo();
3208 ASSERT_TRUE(response);
3209 ASSERT_TRUE(response->headers);
3210 EXPECT_TRUE(response->headers->IsKeepAlive());
3211 EXPECT_EQ(407, response->headers->response_code());
3212 EXPECT_EQ(10, response->headers->GetContentLength());
3213 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3214 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013215
mmenked39192ee2015-12-09 00:57:233216 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013217
mmenked39192ee2015-12-09 00:57:233218 // Wrong password (should be "bar").
3219 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
3220 callback2.callback());
3221 EXPECT_EQ(OK, callback2.GetResult(rv));
ttuttle34f63b52015-03-05 04:33:013222
mmenked39192ee2015-12-09 00:57:233223 response = trans->GetResponseInfo();
3224 ASSERT_TRUE(response);
3225 ASSERT_TRUE(response->headers);
3226 EXPECT_TRUE(response->headers->IsKeepAlive());
3227 EXPECT_EQ(407, response->headers->response_code());
3228 EXPECT_EQ(10, response->headers->GetContentLength());
3229 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3230 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013231
mmenked39192ee2015-12-09 00:57:233232 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3233 // out of scope.
3234 session->CloseAllConnections();
3235 }
ttuttle34f63b52015-03-05 04:33:013236}
3237
3238// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3239// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
3240TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233241 // On the second pass, the body read of the auth challenge is synchronous, so
3242 // IsConnectedAndIdle returns false. The socket should still be drained and
3243 // reused. See http://crbug.com/544255.
3244 for (int i = 0; i < 2; ++i) {
3245 HttpRequestInfo request;
3246 request.method = "GET";
3247 request.url = GURL("https://www.example.org/");
3248 // Ensure that proxy authentication is attempted even
3249 // when the no authentication data flag is set.
3250 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3251
3252 // Configure against proxy server "myproxy:70".
3253 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3254 BoundTestNetLog log;
3255 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093256 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233257
danakj1fd259a02016-04-16 03:17:093258 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:233259 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3260
3261 // Since we have proxy, should try to establish tunnel.
3262 MockWrite data_writes1[] = {
3263 MockWrite(ASYNC, 0,
3264 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3265 "Host: www.example.org:443\r\n"
3266 "Proxy-Connection: keep-alive\r\n\r\n"),
3267
3268 // After calling trans->RestartWithAuth(), this is the request we should
3269 // be issuing -- the final header line contains the credentials.
3270 MockWrite(ASYNC, 3,
3271 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3272 "Host: www.example.org:443\r\n"
3273 "Proxy-Connection: keep-alive\r\n"
3274 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3275 };
3276
3277 // The proxy responds to the connect with a 407, using a persistent
3278 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3279 MockRead data_reads1[] = {
3280 // No credentials.
3281 MockRead(ASYNC, 1,
3282 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3283 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3284 "Content-Length: 10\r\n\r\n"),
3285 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3286
3287 // Wrong credentials (wrong password).
3288 MockRead(ASYNC, 4,
3289 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3290 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3291 "Content-Length: 10\r\n\r\n"),
3292 // No response body because the test stops reading here.
3293 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3294 };
3295
3296 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3297 arraysize(data_writes1));
3298 data1.set_busy_before_sync_reads(true);
3299 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3300
3301 TestCompletionCallback callback1;
3302
3303 int rv = trans->Start(&request, callback1.callback(), log.bound());
3304 EXPECT_EQ(OK, callback1.GetResult(rv));
3305
3306 TestNetLogEntry::List entries;
3307 log.GetEntries(&entries);
3308 size_t pos = ExpectLogContainsSomewhere(
3309 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3310 NetLog::PHASE_NONE);
3311 ExpectLogContainsSomewhere(
3312 entries, pos,
3313 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3314 NetLog::PHASE_NONE);
3315
3316 const HttpResponseInfo* response = trans->GetResponseInfo();
3317 ASSERT_TRUE(response);
3318 ASSERT_TRUE(response->headers);
3319 EXPECT_TRUE(response->headers->IsKeepAlive());
3320 EXPECT_EQ(407, response->headers->response_code());
3321 EXPECT_EQ(10, response->headers->GetContentLength());
3322 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3323 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3324
3325 TestCompletionCallback callback2;
3326
3327 // Wrong password (should be "bar").
3328 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
3329 callback2.callback());
3330 EXPECT_EQ(OK, callback2.GetResult(rv));
3331
3332 response = trans->GetResponseInfo();
3333 ASSERT_TRUE(response);
3334 ASSERT_TRUE(response->headers);
3335 EXPECT_TRUE(response->headers->IsKeepAlive());
3336 EXPECT_EQ(407, response->headers->response_code());
3337 EXPECT_EQ(10, response->headers->GetContentLength());
3338 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3339 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3340
3341 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3342 // out of scope.
3343 session->CloseAllConnections();
3344 }
3345}
3346
3347// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3348// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3349// the case the server sends extra data on the original socket, so it can't be
3350// reused.
3351TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273352 HttpRequestInfo request;
3353 request.method = "GET";
bncce36dca22015-04-21 22:11:233354 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273355 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293356 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273357
[email protected]2d2697f92009-02-18 21:00:323358 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233359 session_deps_.proxy_service =
3360 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513361 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073362 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093363 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323364
[email protected]2d2697f92009-02-18 21:00:323365 // Since we have proxy, should try to establish tunnel.
3366 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233367 MockWrite(ASYNC, 0,
3368 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173369 "Host: www.example.org:443\r\n"
3370 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233371 };
[email protected]2d2697f92009-02-18 21:00:323372
mmenked39192ee2015-12-09 00:57:233373 // The proxy responds to the connect with a 407, using a persistent, but sends
3374 // extra data, so the socket cannot be reused.
3375 MockRead data_reads1[] = {
3376 // No credentials.
3377 MockRead(ASYNC, 1,
3378 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3379 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3380 "Content-Length: 10\r\n\r\n"),
3381 MockRead(SYNCHRONOUS, 2, "0123456789"),
3382 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3383 };
3384
3385 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233386 // After calling trans->RestartWithAuth(), this is the request we should
3387 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233388 MockWrite(ASYNC, 0,
3389 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173390 "Host: www.example.org:443\r\n"
3391 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233392 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3393
3394 MockWrite(ASYNC, 2,
3395 "GET / HTTP/1.1\r\n"
3396 "Host: www.example.org\r\n"
3397 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323398 };
3399
mmenked39192ee2015-12-09 00:57:233400 MockRead data_reads2[] = {
3401 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323402
mmenked39192ee2015-12-09 00:57:233403 MockRead(ASYNC, 3,
3404 "HTTP/1.1 200 OK\r\n"
3405 "Content-Type: text/html; charset=iso-8859-1\r\n"
3406 "Content-Length: 5\r\n\r\n"),
3407 // No response body because the test stops reading here.
3408 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323409 };
3410
mmenked39192ee2015-12-09 00:57:233411 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3412 arraysize(data_writes1));
3413 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073414 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233415 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3416 arraysize(data_writes2));
3417 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3418 SSLSocketDataProvider ssl(ASYNC, OK);
3419 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323420
[email protected]49639fa2011-12-20 23:22:413421 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323422
danakj1fd259a02016-04-16 03:17:093423 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:233424 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:323425
mmenked39192ee2015-12-09 00:57:233426 int rv = trans->Start(&request, callback1.callback(), log.bound());
3427 EXPECT_EQ(OK, callback1.GetResult(rv));
3428
mmenke43758e62015-05-04 21:09:463429 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403430 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393431 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403432 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:393433 NetLog::PHASE_NONE);
3434 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403435 entries, pos,
[email protected]dbb83db2010-05-11 18:13:393436 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3437 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:323438
[email protected]1c773ea12009-04-28 19:58:423439 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243440 ASSERT_TRUE(response);
3441 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323442 EXPECT_TRUE(response->headers->IsKeepAlive());
3443 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423444 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043445 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323446
mmenked39192ee2015-12-09 00:57:233447 LoadTimingInfo load_timing_info;
3448 // CONNECT requests and responses are handled at the connect job level, so
3449 // the transaction does not yet have a connection.
3450 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3451
[email protected]49639fa2011-12-20 23:22:413452 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323453
mmenked39192ee2015-12-09 00:57:233454 rv =
3455 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3456 EXPECT_EQ(OK, callback2.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:323457
[email protected]2d2697f92009-02-18 21:00:323458 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233459 EXPECT_EQ(200, response->headers->response_code());
3460 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423461 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133462
mmenked39192ee2015-12-09 00:57:233463 // The password prompt info should not be set.
3464 EXPECT_FALSE(response->auth_challenge);
3465
3466 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3467 TestLoadTimingNotReusedWithPac(load_timing_info,
3468 CONNECT_TIMING_HAS_SSL_TIMES);
3469
3470 trans.reset();
[email protected]102e27c2011-02-23 01:01:313471 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323472}
3473
mmenkee71e15332015-10-07 16:39:543474// Test the case a proxy closes a socket while the challenge body is being
3475// drained.
3476TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
3477 HttpRequestInfo request;
3478 request.method = "GET";
3479 request.url = GURL("https://www.example.org/");
3480 // Ensure that proxy authentication is attempted even
3481 // when the no authentication data flag is set.
3482 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3483
3484 // Configure against proxy server "myproxy:70".
3485 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093486 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543487
danakj1fd259a02016-04-16 03:17:093488 std::unique_ptr<HttpTransaction> trans(
mmenkee71e15332015-10-07 16:39:543489 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3490
3491 // Since we have proxy, should try to establish tunnel.
3492 MockWrite data_writes1[] = {
3493 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173494 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543495 "Proxy-Connection: keep-alive\r\n\r\n"),
3496 };
3497
3498 // The proxy responds to the connect with a 407, using a persistent
3499 // connection.
3500 MockRead data_reads1[] = {
3501 // No credentials.
3502 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3503 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3504 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3505 // Server hands up in the middle of the body.
3506 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3507 };
3508
3509 MockWrite data_writes2[] = {
3510 // After calling trans->RestartWithAuth(), this is the request we should
3511 // be issuing -- the final header line contains the credentials.
3512 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173513 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543514 "Proxy-Connection: keep-alive\r\n"
3515 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3516
3517 MockWrite("GET / HTTP/1.1\r\n"
3518 "Host: www.example.org\r\n"
3519 "Connection: keep-alive\r\n\r\n"),
3520 };
3521
3522 MockRead data_reads2[] = {
3523 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3524
3525 MockRead("HTTP/1.1 200 OK\r\n"),
3526 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3527 MockRead("Content-Length: 5\r\n\r\n"),
3528 MockRead(SYNCHRONOUS, "hello"),
3529 };
3530
3531 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3532 data_writes1, arraysize(data_writes1));
3533 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3534 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3535 data_writes2, arraysize(data_writes2));
3536 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3537 SSLSocketDataProvider ssl(ASYNC, OK);
3538 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3539
3540 TestCompletionCallback callback;
3541
3542 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3543 EXPECT_EQ(OK, callback.GetResult(rv));
3544
3545 const HttpResponseInfo* response = trans->GetResponseInfo();
3546 ASSERT_TRUE(response);
3547 ASSERT_TRUE(response->headers);
3548 EXPECT_TRUE(response->headers->IsKeepAlive());
3549 EXPECT_EQ(407, response->headers->response_code());
3550 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3551
3552 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
3553 EXPECT_EQ(OK, callback.GetResult(rv));
3554
3555 response = trans->GetResponseInfo();
3556 ASSERT_TRUE(response);
3557 ASSERT_TRUE(response->headers);
3558 EXPECT_TRUE(response->headers->IsKeepAlive());
3559 EXPECT_EQ(200, response->headers->response_code());
3560 std::string body;
3561 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
3562 EXPECT_EQ("hello", body);
3563}
3564
[email protected]a8e9b162009-03-12 00:06:443565// Test that we don't read the response body when we fail to establish a tunnel,
3566// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:023567TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273568 HttpRequestInfo request;
3569 request.method = "GET";
bncce36dca22015-04-21 22:11:233570 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273571 request.load_flags = 0;
3572
[email protected]a8e9b162009-03-12 00:06:443573 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033574 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443575
danakj1fd259a02016-04-16 03:17:093576 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443577
danakj1fd259a02016-04-16 03:17:093578 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503579 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:443580
[email protected]a8e9b162009-03-12 00:06:443581 // Since we have proxy, should try to establish tunnel.
3582 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173583 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3584 "Host: www.example.org:443\r\n"
3585 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443586 };
3587
3588 // The proxy responds to the connect with a 407.
3589 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243590 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3591 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3592 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233593 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243594 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443595 };
3596
[email protected]31a2bfe2010-02-09 08:03:393597 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3598 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073599 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443600
[email protected]49639fa2011-12-20 23:22:413601 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443602
[email protected]49639fa2011-12-20 23:22:413603 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423604 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:443605
3606 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423607 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:443608
[email protected]1c773ea12009-04-28 19:58:423609 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243610 ASSERT_TRUE(response);
3611 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443612 EXPECT_TRUE(response->headers->IsKeepAlive());
3613 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423614 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443615
3616 std::string response_data;
3617 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423618 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:183619
3620 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313621 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443622}
3623
ttuttle7933c112015-01-06 00:55:243624// Test that we don't pass extraneous headers from the proxy's response to the
3625// caller when the proxy responds to CONNECT with 407.
3626TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3627 HttpRequestInfo request;
3628 request.method = "GET";
bncce36dca22015-04-21 22:11:233629 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243630 request.load_flags = 0;
3631
3632 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033633 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243634
danakj1fd259a02016-04-16 03:17:093635 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243636
danakj1fd259a02016-04-16 03:17:093637 std::unique_ptr<HttpTransaction> trans(
ttuttle7933c112015-01-06 00:55:243638 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3639
3640 // Since we have proxy, should try to establish tunnel.
3641 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173642 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3643 "Host: www.example.org:443\r\n"
3644 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243645 };
3646
3647 // The proxy responds to the connect with a 407.
3648 MockRead data_reads[] = {
3649 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3650 MockRead("X-Foo: bar\r\n"),
3651 MockRead("Set-Cookie: foo=bar\r\n"),
3652 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3653 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233654 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243655 };
3656
3657 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3658 arraysize(data_writes));
3659 session_deps_.socket_factory->AddSocketDataProvider(&data);
3660
3661 TestCompletionCallback callback;
3662
3663 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3664 EXPECT_EQ(ERR_IO_PENDING, rv);
3665
3666 rv = callback.WaitForResult();
3667 EXPECT_EQ(OK, rv);
3668
3669 const HttpResponseInfo* response = trans->GetResponseInfo();
3670 ASSERT_TRUE(response);
3671 ASSERT_TRUE(response->headers);
3672 EXPECT_TRUE(response->headers->IsKeepAlive());
3673 EXPECT_EQ(407, response->headers->response_code());
3674 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3675 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3676 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3677
3678 std::string response_data;
3679 rv = ReadTransaction(trans.get(), &response_data);
3680 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3681
3682 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3683 session->CloseAllConnections();
3684}
3685
[email protected]8fdbcd22010-05-05 02:54:523686// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3687// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023688TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523689 HttpRequestInfo request;
3690 request.method = "GET";
bncce36dca22015-04-21 22:11:233691 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523692 request.load_flags = 0;
3693
[email protected]cb9bf6ca2011-01-28 13:15:273694 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3696 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413697 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273698
[email protected]8fdbcd22010-05-05 02:54:523699 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233700 MockWrite(
3701 "GET / HTTP/1.1\r\n"
3702 "Host: www.example.org\r\n"
3703 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523704 };
3705
3706 MockRead data_reads1[] = {
3707 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3708 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3709 // Large content-length -- won't matter, as connection will be reset.
3710 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063711 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523712 };
3713
3714 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3715 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073716 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523717
[email protected]49639fa2011-12-20 23:22:413718 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523719
[email protected]49639fa2011-12-20 23:22:413720 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523721 EXPECT_EQ(ERR_IO_PENDING, rv);
3722
3723 rv = callback.WaitForResult();
3724 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3725}
3726
[email protected]7a67a8152010-11-05 18:31:103727// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3728// through a non-authenticating proxy. The request should fail with
3729// ERR_UNEXPECTED_PROXY_AUTH.
3730// Note that it is impossible to detect if an HTTP server returns a 407 through
3731// a non-authenticating proxy - there is nothing to indicate whether the
3732// response came from the proxy or the server, so it is treated as if the proxy
3733// issued the challenge.
[email protected]23e482282013-06-14 16:08:023734TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233735 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273736 HttpRequestInfo request;
3737 request.method = "GET";
bncce36dca22015-04-21 22:11:233738 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273739
rdsmith82957ad2015-09-16 19:42:033740 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513741 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073742 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093743 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103744
[email protected]7a67a8152010-11-05 18:31:103745 // Since we have proxy, should try to establish tunnel.
3746 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173747 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3748 "Host: www.example.org:443\r\n"
3749 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103750
rsleevidb16bb02015-11-12 23:47:173751 MockWrite("GET / HTTP/1.1\r\n"
3752 "Host: www.example.org\r\n"
3753 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103754 };
3755
3756 MockRead data_reads1[] = {
3757 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3758
3759 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3760 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3761 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063762 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103763 };
3764
3765 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3766 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073767 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063768 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103770
[email protected]49639fa2011-12-20 23:22:413771 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103772
danakj1fd259a02016-04-16 03:17:093773 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503774 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103775
[email protected]49639fa2011-12-20 23:22:413776 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103777 EXPECT_EQ(ERR_IO_PENDING, rv);
3778
3779 rv = callback1.WaitForResult();
3780 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463781 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403782 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103783 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403784 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103785 NetLog::PHASE_NONE);
3786 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403787 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103788 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3789 NetLog::PHASE_NONE);
3790}
[email protected]2df19bb2010-08-25 20:13:463791
mmenke2a1781d2015-10-07 19:25:333792// Test a proxy auth scheme that allows default credentials and a proxy server
3793// that uses non-persistent connections.
3794TEST_P(HttpNetworkTransactionTest,
3795 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3796 HttpRequestInfo request;
3797 request.method = "GET";
3798 request.url = GURL("https://www.example.org/");
3799
3800 // Configure against proxy server "myproxy:70".
3801 session_deps_.proxy_service =
3802 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3803
danakj1fd259a02016-04-16 03:17:093804 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333805 new HttpAuthHandlerMock::Factory());
3806 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093807 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333808 mock_handler->set_allows_default_credentials(true);
3809 auth_handler_factory->AddMockHandler(mock_handler.release(),
3810 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483811 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333812
3813 // Add NetLog just so can verify load timing information gets a NetLog ID.
3814 NetLog net_log;
3815 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093816 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333817
3818 // Since we have proxy, should try to establish tunnel.
3819 MockWrite data_writes1[] = {
3820 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173821 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333822 "Proxy-Connection: keep-alive\r\n\r\n"),
3823 };
3824
3825 // The proxy responds to the connect with a 407, using a non-persistent
3826 // connection.
3827 MockRead data_reads1[] = {
3828 // No credentials.
3829 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3830 MockRead("Proxy-Authenticate: Mock\r\n"),
3831 MockRead("Proxy-Connection: close\r\n\r\n"),
3832 };
3833
3834 // Since the first connection couldn't be reused, need to establish another
3835 // once given credentials.
3836 MockWrite data_writes2[] = {
3837 // After calling trans->RestartWithAuth(), this is the request we should
3838 // be issuing -- the final header line contains the credentials.
3839 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173840 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333841 "Proxy-Connection: keep-alive\r\n"
3842 "Proxy-Authorization: auth_token\r\n\r\n"),
3843
3844 MockWrite("GET / HTTP/1.1\r\n"
3845 "Host: www.example.org\r\n"
3846 "Connection: keep-alive\r\n\r\n"),
3847 };
3848
3849 MockRead data_reads2[] = {
3850 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3851
3852 MockRead("HTTP/1.1 200 OK\r\n"),
3853 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3854 MockRead("Content-Length: 5\r\n\r\n"),
3855 MockRead(SYNCHRONOUS, "hello"),
3856 };
3857
3858 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3859 data_writes1, arraysize(data_writes1));
3860 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3861 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3862 data_writes2, arraysize(data_writes2));
3863 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3864 SSLSocketDataProvider ssl(ASYNC, OK);
3865 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3866
danakj1fd259a02016-04-16 03:17:093867 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3869
3870 TestCompletionCallback callback;
3871 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3872 EXPECT_EQ(OK, callback.GetResult(rv));
3873
3874 const HttpResponseInfo* response = trans->GetResponseInfo();
3875 ASSERT_TRUE(response);
3876 ASSERT_TRUE(response->headers);
3877 EXPECT_FALSE(response->headers->IsKeepAlive());
3878 EXPECT_EQ(407, response->headers->response_code());
3879 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3880 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523881 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333882
3883 LoadTimingInfo load_timing_info;
3884 // CONNECT requests and responses are handled at the connect job level, so
3885 // the transaction does not yet have a connection.
3886 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3887
3888 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3889 EXPECT_EQ(OK, callback.GetResult(rv));
3890 response = trans->GetResponseInfo();
3891 ASSERT_TRUE(response);
3892 ASSERT_TRUE(response->headers);
3893 EXPECT_TRUE(response->headers->IsKeepAlive());
3894 EXPECT_EQ(200, response->headers->response_code());
3895 EXPECT_EQ(5, response->headers->GetContentLength());
3896 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3897
3898 // The password prompt info should not be set.
3899 EXPECT_FALSE(response->auth_challenge);
3900
3901 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3902 TestLoadTimingNotReusedWithPac(load_timing_info,
3903 CONNECT_TIMING_HAS_SSL_TIMES);
3904
3905 trans.reset();
3906 session->CloseAllConnections();
3907}
3908
3909// Test a proxy auth scheme that allows default credentials and a proxy server
3910// that hangs up when credentials are initially sent.
3911TEST_P(HttpNetworkTransactionTest,
3912 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3913 HttpRequestInfo request;
3914 request.method = "GET";
3915 request.url = GURL("https://www.example.org/");
3916
3917 // Configure against proxy server "myproxy:70".
3918 session_deps_.proxy_service =
3919 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3920
danakj1fd259a02016-04-16 03:17:093921 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333922 new HttpAuthHandlerMock::Factory());
3923 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093924 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333925 mock_handler->set_allows_default_credentials(true);
3926 auth_handler_factory->AddMockHandler(mock_handler.release(),
3927 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483928 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333929
3930 // Add NetLog just so can verify load timing information gets a NetLog ID.
3931 NetLog net_log;
3932 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093933 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333934
3935 // Should try to establish tunnel.
3936 MockWrite data_writes1[] = {
3937 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173938 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333939 "Proxy-Connection: keep-alive\r\n\r\n"),
3940
3941 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173942 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333943 "Proxy-Connection: keep-alive\r\n"
3944 "Proxy-Authorization: auth_token\r\n\r\n"),
3945 };
3946
3947 // The proxy responds to the connect with a 407, using a non-persistent
3948 // connection.
3949 MockRead data_reads1[] = {
3950 // No credentials.
3951 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3952 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3953 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3954 };
3955
3956 // Since the first connection was closed, need to establish another once given
3957 // credentials.
3958 MockWrite data_writes2[] = {
3959 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173960 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333961 "Proxy-Connection: keep-alive\r\n"
3962 "Proxy-Authorization: auth_token\r\n\r\n"),
3963
3964 MockWrite("GET / HTTP/1.1\r\n"
3965 "Host: www.example.org\r\n"
3966 "Connection: keep-alive\r\n\r\n"),
3967 };
3968
3969 MockRead data_reads2[] = {
3970 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3971
3972 MockRead("HTTP/1.1 200 OK\r\n"),
3973 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3974 MockRead("Content-Length: 5\r\n\r\n"),
3975 MockRead(SYNCHRONOUS, "hello"),
3976 };
3977
3978 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3979 data_writes1, arraysize(data_writes1));
3980 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3981 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3982 data_writes2, arraysize(data_writes2));
3983 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3984 SSLSocketDataProvider ssl(ASYNC, OK);
3985 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3986
danakj1fd259a02016-04-16 03:17:093987 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333988 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3989
3990 TestCompletionCallback callback;
3991 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3992 EXPECT_EQ(OK, callback.GetResult(rv));
3993
3994 const HttpResponseInfo* response = trans->GetResponseInfo();
3995 ASSERT_TRUE(response);
3996 ASSERT_TRUE(response->headers);
3997 EXPECT_TRUE(response->headers->IsKeepAlive());
3998 EXPECT_EQ(407, response->headers->response_code());
3999 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4000 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4001 EXPECT_FALSE(response->auth_challenge);
4002
4003 LoadTimingInfo load_timing_info;
4004 // CONNECT requests and responses are handled at the connect job level, so
4005 // the transaction does not yet have a connection.
4006 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4007
4008 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4009 EXPECT_EQ(OK, callback.GetResult(rv));
4010
4011 response = trans->GetResponseInfo();
4012 ASSERT_TRUE(response);
4013 ASSERT_TRUE(response->headers);
4014 EXPECT_TRUE(response->headers->IsKeepAlive());
4015 EXPECT_EQ(200, response->headers->response_code());
4016 EXPECT_EQ(5, response->headers->GetContentLength());
4017 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4018
4019 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524020 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334021
4022 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4023 TestLoadTimingNotReusedWithPac(load_timing_info,
4024 CONNECT_TIMING_HAS_SSL_TIMES);
4025
4026 trans.reset();
4027 session->CloseAllConnections();
4028}
4029
4030// Test a proxy auth scheme that allows default credentials and a proxy server
4031// that hangs up when credentials are initially sent, and hangs up again when
4032// they are retried.
4033TEST_P(HttpNetworkTransactionTest,
4034 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4035 HttpRequestInfo request;
4036 request.method = "GET";
4037 request.url = GURL("https://www.example.org/");
4038
4039 // Configure against proxy server "myproxy:70".
4040 session_deps_.proxy_service =
4041 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4042
danakj1fd259a02016-04-16 03:17:094043 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334044 new HttpAuthHandlerMock::Factory());
4045 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094046 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334047 mock_handler->set_allows_default_credentials(true);
4048 auth_handler_factory->AddMockHandler(mock_handler.release(),
4049 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484050 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334051
4052 // Add NetLog just so can verify load timing information gets a NetLog ID.
4053 NetLog net_log;
4054 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094055 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334056
4057 // Should try to establish tunnel.
4058 MockWrite data_writes1[] = {
4059 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174060 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334061 "Proxy-Connection: keep-alive\r\n\r\n"),
4062
4063 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174064 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334065 "Proxy-Connection: keep-alive\r\n"
4066 "Proxy-Authorization: auth_token\r\n\r\n"),
4067 };
4068
4069 // The proxy responds to the connect with a 407, and then hangs up after the
4070 // second request is sent.
4071 MockRead data_reads1[] = {
4072 // No credentials.
4073 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4074 MockRead("Content-Length: 0\r\n"),
4075 MockRead("Proxy-Connection: keep-alive\r\n"),
4076 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4077 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4078 };
4079
4080 // HttpNetworkTransaction sees a reused connection that was closed with
4081 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4082 // request.
4083 MockWrite data_writes2[] = {
4084 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174085 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334086 "Proxy-Connection: keep-alive\r\n\r\n"),
4087 };
4088
4089 // The proxy, having had more than enough of us, just hangs up.
4090 MockRead data_reads2[] = {
4091 // No credentials.
4092 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4093 };
4094
4095 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4096 data_writes1, arraysize(data_writes1));
4097 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4098 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4099 data_writes2, arraysize(data_writes2));
4100 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4101
danakj1fd259a02016-04-16 03:17:094102 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334103 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4104
4105 TestCompletionCallback callback;
4106 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4107 EXPECT_EQ(OK, callback.GetResult(rv));
4108
4109 const HttpResponseInfo* response = trans->GetResponseInfo();
4110 ASSERT_TRUE(response);
4111 ASSERT_TRUE(response->headers);
4112 EXPECT_TRUE(response->headers->IsKeepAlive());
4113 EXPECT_EQ(407, response->headers->response_code());
4114 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4115 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4116 EXPECT_FALSE(response->auth_challenge);
4117
4118 LoadTimingInfo load_timing_info;
4119 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4120
4121 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4122 EXPECT_EQ(ERR_EMPTY_RESPONSE, callback.GetResult(rv));
4123
4124 trans.reset();
4125 session->CloseAllConnections();
4126}
4127
4128// Test a proxy auth scheme that allows default credentials and a proxy server
4129// that hangs up when credentials are initially sent, and sends a challenge
4130// again they are retried.
4131TEST_P(HttpNetworkTransactionTest,
4132 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4133 HttpRequestInfo request;
4134 request.method = "GET";
4135 request.url = GURL("https://www.example.org/");
4136
4137 // Configure against proxy server "myproxy:70".
4138 session_deps_.proxy_service =
4139 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4140
danakj1fd259a02016-04-16 03:17:094141 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334142 new HttpAuthHandlerMock::Factory());
4143 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094144 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334145 mock_handler->set_allows_default_credentials(true);
4146 auth_handler_factory->AddMockHandler(mock_handler.release(),
4147 HttpAuth::AUTH_PROXY);
4148 // Add another handler for the second challenge. It supports default
4149 // credentials, but they shouldn't be used, since they were already tried.
4150 mock_handler.reset(new HttpAuthHandlerMock());
4151 mock_handler->set_allows_default_credentials(true);
4152 auth_handler_factory->AddMockHandler(mock_handler.release(),
4153 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484154 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334155
4156 // Add NetLog just so can verify load timing information gets a NetLog ID.
4157 NetLog net_log;
4158 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094159 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334160
4161 // Should try to establish tunnel.
4162 MockWrite data_writes1[] = {
4163 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174164 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334165 "Proxy-Connection: keep-alive\r\n\r\n"),
4166 };
4167
4168 // The proxy responds to the connect with a 407, using a non-persistent
4169 // connection.
4170 MockRead data_reads1[] = {
4171 // No credentials.
4172 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4173 MockRead("Proxy-Authenticate: Mock\r\n"),
4174 MockRead("Proxy-Connection: close\r\n\r\n"),
4175 };
4176
4177 // Since the first connection was closed, need to establish another once given
4178 // credentials.
4179 MockWrite data_writes2[] = {
4180 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174181 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334182 "Proxy-Connection: keep-alive\r\n"
4183 "Proxy-Authorization: auth_token\r\n\r\n"),
4184 };
4185
4186 MockRead data_reads2[] = {
4187 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4188 MockRead("Proxy-Authenticate: Mock\r\n"),
4189 MockRead("Proxy-Connection: close\r\n\r\n"),
4190 };
4191
4192 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4193 data_writes1, arraysize(data_writes1));
4194 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4195 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4196 data_writes2, arraysize(data_writes2));
4197 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4198 SSLSocketDataProvider ssl(ASYNC, OK);
4199 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4200
danakj1fd259a02016-04-16 03:17:094201 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334202 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4203
4204 TestCompletionCallback callback;
4205 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4206 EXPECT_EQ(OK, callback.GetResult(rv));
4207
4208 const HttpResponseInfo* response = trans->GetResponseInfo();
4209 ASSERT_TRUE(response);
4210 ASSERT_TRUE(response->headers);
4211 EXPECT_EQ(407, response->headers->response_code());
4212 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4213 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4214 EXPECT_FALSE(response->auth_challenge);
4215
4216 LoadTimingInfo load_timing_info;
4217 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4218
4219 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4220 EXPECT_EQ(OK, callback.GetResult(rv));
4221 response = trans->GetResponseInfo();
4222 ASSERT_TRUE(response);
4223 ASSERT_TRUE(response->headers);
4224 EXPECT_EQ(407, response->headers->response_code());
4225 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4226 EXPECT_TRUE(response->auth_challenge);
4227
4228 trans.reset();
4229 session->CloseAllConnections();
4230}
4231
[email protected]029c83b62013-01-24 05:28:204232// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:024233TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204234 HttpRequestInfo request1;
4235 request1.method = "GET";
bncce36dca22015-04-21 22:11:234236 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204237
4238 HttpRequestInfo request2;
4239 request2.method = "GET";
bncce36dca22015-04-21 22:11:234240 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204241
4242 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034243 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514244 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074245 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094246 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204247
4248 // Since we have proxy, should try to establish tunnel.
4249 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174250 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4251 "Host: www.example.org:443\r\n"
4252 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204253
rsleevidb16bb02015-11-12 23:47:174254 MockWrite("GET /1 HTTP/1.1\r\n"
4255 "Host: www.example.org\r\n"
4256 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204257
rsleevidb16bb02015-11-12 23:47:174258 MockWrite("GET /2 HTTP/1.1\r\n"
4259 "Host: www.example.org\r\n"
4260 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204261 };
4262
4263 // The proxy responds to the connect with a 407, using a persistent
4264 // connection.
4265 MockRead data_reads1[] = {
4266 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4267
4268 MockRead("HTTP/1.1 200 OK\r\n"),
4269 MockRead("Content-Length: 1\r\n\r\n"),
4270 MockRead(SYNCHRONOUS, "1"),
4271
4272 MockRead("HTTP/1.1 200 OK\r\n"),
4273 MockRead("Content-Length: 2\r\n\r\n"),
4274 MockRead(SYNCHRONOUS, "22"),
4275 };
4276
4277 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4278 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074279 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204280 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074281 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204282
4283 TestCompletionCallback callback1;
danakj1fd259a02016-04-16 03:17:094284 std::unique_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:504285 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204286
4287 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
4288 EXPECT_EQ(ERR_IO_PENDING, rv);
4289
4290 rv = callback1.WaitForResult();
4291 EXPECT_EQ(OK, rv);
4292
4293 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524294 ASSERT_TRUE(response1);
4295 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204296 EXPECT_EQ(1, response1->headers->GetContentLength());
4297
4298 LoadTimingInfo load_timing_info1;
4299 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4300 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4301
4302 trans1.reset();
4303
4304 TestCompletionCallback callback2;
danakj1fd259a02016-04-16 03:17:094305 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204307
4308 rv = trans2->Start(&request2, callback2.callback(), log.bound());
4309 EXPECT_EQ(ERR_IO_PENDING, rv);
4310
4311 rv = callback2.WaitForResult();
4312 EXPECT_EQ(OK, rv);
4313
4314 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524315 ASSERT_TRUE(response2);
4316 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204317 EXPECT_EQ(2, response2->headers->GetContentLength());
4318
4319 LoadTimingInfo load_timing_info2;
4320 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4321 TestLoadTimingReused(load_timing_info2);
4322
4323 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4324
4325 trans2.reset();
4326 session->CloseAllConnections();
4327}
4328
4329// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:024330TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204331 HttpRequestInfo request1;
4332 request1.method = "GET";
bncce36dca22015-04-21 22:11:234333 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204334
4335 HttpRequestInfo request2;
4336 request2.method = "GET";
bncce36dca22015-04-21 22:11:234337 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204338
4339 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034340 session_deps_.proxy_service =
4341 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514342 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074343 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094344 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204345
4346 // Since we have proxy, should try to establish tunnel.
4347 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174348 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4349 "Host: www.example.org:443\r\n"
4350 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204351
rsleevidb16bb02015-11-12 23:47:174352 MockWrite("GET /1 HTTP/1.1\r\n"
4353 "Host: www.example.org\r\n"
4354 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204355
rsleevidb16bb02015-11-12 23:47:174356 MockWrite("GET /2 HTTP/1.1\r\n"
4357 "Host: www.example.org\r\n"
4358 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204359 };
4360
4361 // The proxy responds to the connect with a 407, using a persistent
4362 // connection.
4363 MockRead data_reads1[] = {
4364 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4365
4366 MockRead("HTTP/1.1 200 OK\r\n"),
4367 MockRead("Content-Length: 1\r\n\r\n"),
4368 MockRead(SYNCHRONOUS, "1"),
4369
4370 MockRead("HTTP/1.1 200 OK\r\n"),
4371 MockRead("Content-Length: 2\r\n\r\n"),
4372 MockRead(SYNCHRONOUS, "22"),
4373 };
4374
4375 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4376 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074377 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204378 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204380
4381 TestCompletionCallback callback1;
danakj1fd259a02016-04-16 03:17:094382 std::unique_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:504383 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204384
4385 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
4386 EXPECT_EQ(ERR_IO_PENDING, rv);
4387
4388 rv = callback1.WaitForResult();
4389 EXPECT_EQ(OK, rv);
4390
4391 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524392 ASSERT_TRUE(response1);
4393 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204394 EXPECT_EQ(1, response1->headers->GetContentLength());
4395
4396 LoadTimingInfo load_timing_info1;
4397 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4398 TestLoadTimingNotReusedWithPac(load_timing_info1,
4399 CONNECT_TIMING_HAS_SSL_TIMES);
4400
4401 trans1.reset();
4402
4403 TestCompletionCallback callback2;
danakj1fd259a02016-04-16 03:17:094404 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204406
4407 rv = trans2->Start(&request2, callback2.callback(), log.bound());
4408 EXPECT_EQ(ERR_IO_PENDING, rv);
4409
4410 rv = callback2.WaitForResult();
4411 EXPECT_EQ(OK, rv);
4412
4413 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524414 ASSERT_TRUE(response2);
4415 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204416 EXPECT_EQ(2, response2->headers->GetContentLength());
4417
4418 LoadTimingInfo load_timing_info2;
4419 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4420 TestLoadTimingReusedWithPac(load_timing_info2);
4421
4422 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4423
4424 trans2.reset();
4425 session->CloseAllConnections();
4426}
4427
[email protected]2df19bb2010-08-25 20:13:464428// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024429TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274430 HttpRequestInfo request;
4431 request.method = "GET";
bncce36dca22015-04-21 22:11:234432 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274433
[email protected]2df19bb2010-08-25 20:13:464434 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034435 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514436 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074437 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094438 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464439
[email protected]2df19bb2010-08-25 20:13:464440 // Since we have proxy, should use full url
4441 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234442 MockWrite(
4443 "GET http://www.example.org/ HTTP/1.1\r\n"
4444 "Host: www.example.org\r\n"
4445 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464446 };
4447
4448 MockRead data_reads1[] = {
4449 MockRead("HTTP/1.1 200 OK\r\n"),
4450 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4451 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064452 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464453 };
4454
4455 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4456 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074457 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064458 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074459 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464460
[email protected]49639fa2011-12-20 23:22:414461 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464462
danakj1fd259a02016-04-16 03:17:094463 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504464 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504465
[email protected]49639fa2011-12-20 23:22:414466 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464467 EXPECT_EQ(ERR_IO_PENDING, rv);
4468
4469 rv = callback1.WaitForResult();
4470 EXPECT_EQ(OK, rv);
4471
[email protected]58e32bb2013-01-21 18:23:254472 LoadTimingInfo load_timing_info;
4473 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4474 TestLoadTimingNotReused(load_timing_info,
4475 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4476
[email protected]2df19bb2010-08-25 20:13:464477 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524478 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464479
4480 EXPECT_TRUE(response->headers->IsKeepAlive());
4481 EXPECT_EQ(200, response->headers->response_code());
4482 EXPECT_EQ(100, response->headers->GetContentLength());
4483 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4484
4485 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524486 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464487}
4488
[email protected]7642b5ae2010-09-01 20:55:174489// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024490TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274491 HttpRequestInfo request;
4492 request.method = "GET";
bncce36dca22015-04-21 22:11:234493 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274494 request.load_flags = 0;
4495
[email protected]7642b5ae2010-09-01 20:55:174496 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034497 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514498 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074499 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094500 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174501
bncce36dca22015-04-21 22:11:234502 // fetch http://www.example.org/ via SPDY
danakj1fd259a02016-04-16 03:17:094503 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:494504 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134505 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174506
danakj1fd259a02016-04-16 03:17:094507 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554508 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:094509 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554510 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174511 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134512 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174513 };
4514
rch8e6c6c42015-05-01 14:05:134515 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4516 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074517 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174518
[email protected]8ddf8322012-02-23 18:08:064519 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384520 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074521 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174522
[email protected]49639fa2011-12-20 23:22:414523 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174524
danakj1fd259a02016-04-16 03:17:094525 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504526 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504527
[email protected]49639fa2011-12-20 23:22:414528 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:174529 EXPECT_EQ(ERR_IO_PENDING, rv);
4530
4531 rv = callback1.WaitForResult();
4532 EXPECT_EQ(OK, rv);
4533
[email protected]58e32bb2013-01-21 18:23:254534 LoadTimingInfo load_timing_info;
4535 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4536 TestLoadTimingNotReused(load_timing_info,
4537 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4538
[email protected]7642b5ae2010-09-01 20:55:174539 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524540 ASSERT_TRUE(response);
4541 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024542 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174543
4544 std::string response_data;
4545 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234546 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174547}
4548
[email protected]1c173852014-06-19 12:51:504549// Verifies that a session which races and wins against the owning transaction
4550// (completing prior to host resolution), doesn't fail the transaction.
4551// Regression test for crbug.com/334413.
4552TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
4553 HttpRequestInfo request;
4554 request.method = "GET";
bncce36dca22015-04-21 22:11:234555 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504556 request.load_flags = 0;
4557
4558 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034559 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514560 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504561 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094562 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504563
bncce36dca22015-04-21 22:11:234564 // Fetch http://www.example.org/ through the SPDY proxy.
danakj1fd259a02016-04-16 03:17:094565 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:494566 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134567 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:504568
danakj1fd259a02016-04-16 03:17:094569 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554570 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094571 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554572 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]1c173852014-06-19 12:51:504573 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134574 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504575 };
4576
rch8e6c6c42015-05-01 14:05:134577 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4578 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504579 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4580
4581 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384582 ssl.SetNextProto(GetProtocol());
[email protected]1c173852014-06-19 12:51:504583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4584
4585 TestCompletionCallback callback1;
4586
danakj1fd259a02016-04-16 03:17:094587 std::unique_ptr<HttpTransaction> trans(
[email protected]1c173852014-06-19 12:51:504588 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4589
4590 // Stall the hostname resolution begun by the transaction.
4591 session_deps_.host_resolver->set_synchronous_mode(false);
4592 session_deps_.host_resolver->set_ondemand_mode(true);
4593
4594 int rv = trans->Start(&request, callback1.callback(), log.bound());
4595 EXPECT_EQ(ERR_IO_PENDING, rv);
4596
4597 // Race a session to the proxy, which completes first.
4598 session_deps_.host_resolver->set_ondemand_mode(false);
4599 SpdySessionKey key(
4600 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4601 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424602 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504603
4604 // Unstall the resolution begun by the transaction.
4605 session_deps_.host_resolver->set_ondemand_mode(true);
4606 session_deps_.host_resolver->ResolveAllPending();
4607
4608 EXPECT_FALSE(callback1.have_result());
4609 rv = callback1.WaitForResult();
4610 EXPECT_EQ(OK, rv);
4611
4612 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524613 ASSERT_TRUE(response);
4614 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024615 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504616
4617 std::string response_data;
4618 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4619 EXPECT_EQ(kUploadData, response_data);
4620}
4621
[email protected]dc7bd1c52010-11-12 00:01:134622// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024623TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274624 HttpRequestInfo request;
4625 request.method = "GET";
bncce36dca22015-04-21 22:11:234626 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274627 request.load_flags = 0;
4628
[email protected]79cb5c12011-09-12 13:12:044629 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034630 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514631 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074632 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094633 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134634
[email protected]dc7bd1c52010-11-12 00:01:134635 // The first request will be a bare GET, the second request will be a
4636 // GET with a Proxy-Authorization header.
danakj1fd259a02016-04-16 03:17:094637 std::unique_ptr<SpdySerializedFrame> req_get(
bnc38dcd392016-02-09 23:19:494638 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384639 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134640 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464641 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134642 };
danakj1fd259a02016-04-16 03:17:094643 std::unique_ptr<SpdySerializedFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:464644 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
bncb03b1092016-04-06 11:19:554645 arraysize(kExtraAuthorizationHeaders) / 2, 3,
4646 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134647 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134648 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134649 };
4650
4651 // The first response is a 407 proxy authentication challenge, and the second
4652 // response will be a 200 response since the second request includes a valid
4653 // Authorization header.
4654 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464655 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134656 };
danakj1fd259a02016-04-16 03:17:094657 std::unique_ptr<SpdySerializedFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:024658 spdy_util_.ConstructSpdySynReplyError(
bncb03b1092016-04-06 11:19:554659 "407 Proxy Authentication Required", kExtraAuthenticationHeaders,
4660 arraysize(kExtraAuthenticationHeaders) / 2, 1));
danakj1fd259a02016-04-16 03:17:094661 std::unique_ptr<SpdySerializedFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:024662 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:094663 std::unique_ptr<SpdySerializedFrame> resp_data(
[email protected]23e482282013-06-14 16:08:024664 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:094665 std::unique_ptr<SpdySerializedFrame> body_data(
bncb03b1092016-04-06 11:19:554666 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134667 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134668 CreateMockRead(*resp_authentication, 1),
4669 CreateMockRead(*body_authentication, 2),
4670 CreateMockRead(*resp_data, 4),
4671 CreateMockRead(*body_data, 5),
4672 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134673 };
4674
rch8e6c6c42015-05-01 14:05:134675 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4676 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074677 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134678
[email protected]8ddf8322012-02-23 18:08:064679 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384680 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074681 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134682
[email protected]49639fa2011-12-20 23:22:414683 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134684
danakj1fd259a02016-04-16 03:17:094685 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504686 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:134687
[email protected]49639fa2011-12-20 23:22:414688 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:134689 EXPECT_EQ(ERR_IO_PENDING, rv);
4690
4691 rv = callback1.WaitForResult();
4692 EXPECT_EQ(OK, rv);
4693
4694 const HttpResponseInfo* const response = trans->GetResponseInfo();
4695
wezca1070932016-05-26 20:30:524696 ASSERT_TRUE(response);
4697 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134698 EXPECT_EQ(407, response->headers->response_code());
4699 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:044700 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134701
[email protected]49639fa2011-12-20 23:22:414702 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134703
[email protected]49639fa2011-12-20 23:22:414704 rv = trans->RestartWithAuth(
4705 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:134706 EXPECT_EQ(ERR_IO_PENDING, rv);
4707
4708 rv = callback2.WaitForResult();
4709 EXPECT_EQ(OK, rv);
4710
4711 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
4712
wezca1070932016-05-26 20:30:524713 ASSERT_TRUE(response_restart);
4714 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134715 EXPECT_EQ(200, response_restart->headers->response_code());
4716 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524717 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134718}
4719
[email protected]d9da5fe2010-10-13 22:37:164720// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:024721TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274722 HttpRequestInfo request;
4723 request.method = "GET";
bncce36dca22015-04-21 22:11:234724 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274725 request.load_flags = 0;
4726
[email protected]d9da5fe2010-10-13 22:37:164727 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034728 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514729 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074730 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164732
danakj1fd259a02016-04-16 03:17:094733 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504734 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164735
bncce36dca22015-04-21 22:11:234736 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094737 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234738 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4739 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164740
bncce36dca22015-04-21 22:11:234741 const char get[] =
4742 "GET / HTTP/1.1\r\n"
4743 "Host: www.example.org\r\n"
4744 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094745 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024746 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
danakj1fd259a02016-04-16 03:17:094747 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:024748 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164749 const char resp[] = "HTTP/1.1 200 OK\r\n"
4750 "Content-Length: 10\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094751 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024752 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
danakj1fd259a02016-04-16 03:17:094753 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024754 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
danakj1fd259a02016-04-16 03:17:094755 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204756 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:044757
4758 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134759 CreateMockWrite(*connect, 0),
4760 CreateMockWrite(*wrapped_get, 2),
4761 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044762 };
4763
[email protected]d9da5fe2010-10-13 22:37:164764 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134765 CreateMockRead(*conn_resp, 1, ASYNC),
4766 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
4767 CreateMockRead(*wrapped_body, 4, ASYNC),
4768 CreateMockRead(*wrapped_body, 5, ASYNC),
4769 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164770 };
4771
rch8e6c6c42015-05-01 14:05:134772 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4773 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074774 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164775
[email protected]8ddf8322012-02-23 18:08:064776 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384777 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074778 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064779 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074780 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164781
[email protected]49639fa2011-12-20 23:22:414782 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164783
[email protected]49639fa2011-12-20 23:22:414784 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164785 EXPECT_EQ(ERR_IO_PENDING, rv);
4786
4787 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:134788 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:164789
[email protected]58e32bb2013-01-21 18:23:254790 LoadTimingInfo load_timing_info;
4791 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4792 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4793
[email protected]d9da5fe2010-10-13 22:37:164794 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524795 ASSERT_TRUE(response);
4796 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164797 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4798
4799 std::string response_data;
4800 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4801 EXPECT_EQ("1234567890", response_data);
4802}
4803
4804// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:024805TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
rdsmithebb50aa2015-11-12 03:44:384806 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
4807
[email protected]cb9bf6ca2011-01-28 13:15:274808 HttpRequestInfo request;
4809 request.method = "GET";
bncce36dca22015-04-21 22:11:234810 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274811 request.load_flags = 0;
4812
[email protected]d9da5fe2010-10-13 22:37:164813 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034814 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514815 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074816 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094817 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164818
danakj1fd259a02016-04-16 03:17:094819 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504820 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164821
bncce36dca22015-04-21 22:11:234822 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094823 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234824 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4825 // fetch https://www.example.org/ via SPDY
4826 const char kMyUrl[] = "https://www.example.org/";
danakj1fd259a02016-04-16 03:17:094827 std::unique_ptr<SpdySerializedFrame> get(
bnc38dcd392016-02-09 23:19:494828 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
danakj1fd259a02016-04-16 03:17:094829 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024830 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
danakj1fd259a02016-04-16 03:17:094831 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:024832 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094833 std::unique_ptr<SpdySerializedFrame> get_resp(
rdsmithebb50aa2015-11-12 03:44:384834 spdy_util_wrapped.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094835 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024836 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
danakj1fd259a02016-04-16 03:17:094837 std::unique_ptr<SpdySerializedFrame> body(
bncb03b1092016-04-06 11:19:554838 spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:094839 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024840 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
danakj1fd259a02016-04-16 03:17:094841 std::unique_ptr<SpdySerializedFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:204842 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
danakj1fd259a02016-04-16 03:17:094843 std::unique_ptr<SpdySerializedFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:204844 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:044845
4846 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:094847 CreateMockWrite(*connect, 0),
4848 CreateMockWrite(*wrapped_get, 2),
4849 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:044850 CreateMockWrite(*window_update_body, 7),
4851 };
4852
[email protected]d9da5fe2010-10-13 22:37:164853 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:094854 CreateMockRead(*conn_resp, 1, ASYNC),
4855 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:134856 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:094857 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134858 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164859 };
4860
rch32320842015-05-16 15:57:094861 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4862 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074863 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164864
[email protected]8ddf8322012-02-23 18:08:064865 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384866 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074867 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064868 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384869 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074870 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164871
[email protected]49639fa2011-12-20 23:22:414872 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164873
[email protected]49639fa2011-12-20 23:22:414874 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164875 EXPECT_EQ(ERR_IO_PENDING, rv);
4876
rch32320842015-05-16 15:57:094877 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:554878 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:094879 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:594880 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:164881 rv = callback1.WaitForResult();
4882 EXPECT_EQ(OK, rv);
4883
[email protected]58e32bb2013-01-21 18:23:254884 LoadTimingInfo load_timing_info;
4885 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4886 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4887
[email protected]d9da5fe2010-10-13 22:37:164888 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524889 ASSERT_TRUE(response);
4890 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024891 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:164892
4893 std::string response_data;
4894 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234895 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:164896}
4897
4898// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024899TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:274900 HttpRequestInfo request;
4901 request.method = "GET";
bncce36dca22015-04-21 22:11:234902 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274903 request.load_flags = 0;
4904
[email protected]d9da5fe2010-10-13 22:37:164905 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034906 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514907 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074908 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164910
danakj1fd259a02016-04-16 03:17:094911 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504912 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164913
bncce36dca22015-04-21 22:11:234914 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094915 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234916 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:094917 std::unique_ptr<SpdySerializedFrame> get(
[email protected]c10b20852013-05-15 21:29:204918 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:164919
4920 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134921 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:164922 };
4923
danakj1fd259a02016-04-16 03:17:094924 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554925 spdy_util_.ConstructSpdySynReplyError(1));
danakj1fd259a02016-04-16 03:17:094926 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554927 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:164928 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134929 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:164930 };
4931
rch8e6c6c42015-05-01 14:05:134932 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4933 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074934 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164935
[email protected]8ddf8322012-02-23 18:08:064936 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384937 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074938 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064939 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384940 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074941 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164942
[email protected]49639fa2011-12-20 23:22:414943 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164944
[email protected]49639fa2011-12-20 23:22:414945 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164946 EXPECT_EQ(ERR_IO_PENDING, rv);
4947
4948 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:174949 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:164950
ttuttle960fcbf2016-04-19 13:26:324951 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:164952}
4953
[email protected]f6c63db52013-02-02 00:35:224954// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4955// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024956TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224957 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
4958 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034959 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514960 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074961 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094962 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504963 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224964
4965 HttpRequestInfo request1;
4966 request1.method = "GET";
bncce36dca22015-04-21 22:11:234967 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224968 request1.load_flags = 0;
4969
4970 HttpRequestInfo request2;
4971 request2.method = "GET";
bncce36dca22015-04-21 22:11:234972 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224973 request2.load_flags = 0;
4974
bncce36dca22015-04-21 22:11:234975 // CONNECT to www.example.org:443 via SPDY.
danakj1fd259a02016-04-16 03:17:094976 std::unique_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234977 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:094978 std::unique_ptr<SpdySerializedFrame> conn_resp1(
[email protected]23e482282013-06-14 16:08:024979 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224980
bncce36dca22015-04-21 22:11:234981 // Fetch https://www.example.org/ via HTTP.
4982 const char get1[] =
4983 "GET / HTTP/1.1\r\n"
4984 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224985 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094986 std::unique_ptr<SpdySerializedFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024987 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224988 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4989 "Content-Length: 1\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094990 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024991 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
danakj1fd259a02016-04-16 03:17:094992 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
[email protected]23e482282013-06-14 16:08:024993 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
danakj1fd259a02016-04-16 03:17:094994 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204995 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224996
bncce36dca22015-04-21 22:11:234997 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:294998 SpdyHeaderBlock connect2_block;
bnc7ecc1122015-09-28 13:22:494999 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]745aa9c2014-06-27 02:21:295000 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
rdsmithebb50aa2015-11-12 03:44:385001 if (GetProtocol() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:325002 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
5003 } else {
bnc6b996d532015-07-29 10:51:325004 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
bnc7ecc1122015-09-28 13:22:495005 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
bnc6b996d532015-07-29 10:51:325006 }
danakj1fd259a02016-04-16 03:17:095007 std::unique_ptr<SpdySerializedFrame> connect2(
bnc38dcd392016-02-09 23:19:495008 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395009
danakj1fd259a02016-04-16 03:17:095010 std::unique_ptr<SpdySerializedFrame> conn_resp2(
[email protected]23e482282013-06-14 16:08:025011 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225012
bncce36dca22015-04-21 22:11:235013 // Fetch https://mail.example.org/ via HTTP.
5014 const char get2[] =
5015 "GET / HTTP/1.1\r\n"
5016 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225017 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095018 std::unique_ptr<SpdySerializedFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:025019 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225020 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5021 "Content-Length: 2\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095022 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:025023 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
danakj1fd259a02016-04-16 03:17:095024 std::unique_ptr<SpdySerializedFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:025025 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225026
5027 MockWrite spdy_writes[] = {
5028 CreateMockWrite(*connect1, 0),
5029 CreateMockWrite(*wrapped_get1, 2),
5030 CreateMockWrite(*connect2, 5),
5031 CreateMockWrite(*wrapped_get2, 7),
5032 };
5033
5034 MockRead spdy_reads[] = {
5035 CreateMockRead(*conn_resp1, 1, ASYNC),
5036 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
5037 CreateMockRead(*wrapped_body1, 4, ASYNC),
5038 CreateMockRead(*conn_resp2, 6, ASYNC),
5039 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
5040 CreateMockRead(*wrapped_body2, 9, ASYNC),
5041 MockRead(ASYNC, 0, 10),
5042 };
5043
mmenke11eb5152015-06-09 14:50:505044 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5045 arraysize(spdy_writes));
5046 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225047
5048 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:385049 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:505050 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225051 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505052 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225053 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505054 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225055
5056 TestCompletionCallback callback;
5057
danakj1fd259a02016-04-16 03:17:095058 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505059 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225060 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505061 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225062
5063 LoadTimingInfo load_timing_info;
5064 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5065 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5066
5067 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525068 ASSERT_TRUE(response);
5069 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225070 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5071
5072 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295073 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505074 rv = trans->Read(buf.get(), 256, callback.callback());
5075 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225076
danakj1fd259a02016-04-16 03:17:095077 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:505078 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225079 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505080 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225081
5082 LoadTimingInfo load_timing_info2;
5083 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5084 // Even though the SPDY connection is reused, a new tunnelled connection has
5085 // to be created, so the socket's load timing looks like a fresh connection.
5086 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5087
5088 // The requests should have different IDs, since they each are using their own
5089 // separate stream.
5090 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5091
mmenke11eb5152015-06-09 14:50:505092 rv = trans2->Read(buf.get(), 256, callback.callback());
5093 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225094}
5095
5096// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5097// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:025098TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225099 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5100 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035101 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515102 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075103 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095104 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505105 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225106
5107 HttpRequestInfo request1;
5108 request1.method = "GET";
bncce36dca22015-04-21 22:11:235109 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225110 request1.load_flags = 0;
5111
5112 HttpRequestInfo request2;
5113 request2.method = "GET";
bncce36dca22015-04-21 22:11:235114 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225115 request2.load_flags = 0;
5116
bncce36dca22015-04-21 22:11:235117 // CONNECT to www.example.org:443 via SPDY.
danakj1fd259a02016-04-16 03:17:095118 std::unique_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235119 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:095120 std::unique_ptr<SpdySerializedFrame> conn_resp1(
[email protected]23e482282013-06-14 16:08:025121 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225122
bncce36dca22015-04-21 22:11:235123 // Fetch https://www.example.org/ via HTTP.
5124 const char get1[] =
5125 "GET / HTTP/1.1\r\n"
5126 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225127 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095128 std::unique_ptr<SpdySerializedFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:025129 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225130 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5131 "Content-Length: 1\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095132 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:025133 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
danakj1fd259a02016-04-16 03:17:095134 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
[email protected]23e482282013-06-14 16:08:025135 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
danakj1fd259a02016-04-16 03:17:095136 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:205137 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:225138
bncce36dca22015-04-21 22:11:235139 // Fetch https://www.example.org/2 via HTTP.
5140 const char get2[] =
5141 "GET /2 HTTP/1.1\r\n"
5142 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225143 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095144 std::unique_ptr<SpdySerializedFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:025145 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225146 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5147 "Content-Length: 2\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095148 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:025149 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
danakj1fd259a02016-04-16 03:17:095150 std::unique_ptr<SpdySerializedFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:025151 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225152
5153 MockWrite spdy_writes[] = {
5154 CreateMockWrite(*connect1, 0),
5155 CreateMockWrite(*wrapped_get1, 2),
5156 CreateMockWrite(*wrapped_get2, 5),
5157 };
5158
5159 MockRead spdy_reads[] = {
5160 CreateMockRead(*conn_resp1, 1, ASYNC),
5161 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
5162 CreateMockRead(*wrapped_body1, 4, ASYNC),
5163 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
5164 CreateMockRead(*wrapped_body2, 7, ASYNC),
5165 MockRead(ASYNC, 0, 8),
5166 };
5167
mmenke11eb5152015-06-09 14:50:505168 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5169 arraysize(spdy_writes));
5170 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225171
5172 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:385173 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:505174 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225175 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505176 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225177
5178 TestCompletionCallback callback;
5179
danakj1fd259a02016-04-16 03:17:095180 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505181 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225182 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
5183 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:225184
5185 rv = callback.WaitForResult();
5186 EXPECT_EQ(OK, rv);
5187
5188 LoadTimingInfo load_timing_info;
5189 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5190 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5191
5192 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525193 ASSERT_TRUE(response);
5194 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225195 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5196
5197 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295198 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505199 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225200 trans.reset();
5201
danakj1fd259a02016-04-16 03:17:095202 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:505203 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225204 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
5205 EXPECT_EQ(ERR_IO_PENDING, rv);
5206
[email protected]f6c63db52013-02-02 00:35:225207 rv = callback.WaitForResult();
5208 EXPECT_EQ(OK, rv);
5209
5210 LoadTimingInfo load_timing_info2;
5211 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5212 TestLoadTimingReused(load_timing_info2);
5213
5214 // The requests should have the same ID.
5215 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5216
[email protected]90499482013-06-01 00:39:505217 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225218}
5219
5220// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5221// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:505222TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225223 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035224 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515225 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075226 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095227 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505228 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225229
5230 HttpRequestInfo request1;
5231 request1.method = "GET";
bncce36dca22015-04-21 22:11:235232 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225233 request1.load_flags = 0;
5234
5235 HttpRequestInfo request2;
5236 request2.method = "GET";
bncce36dca22015-04-21 22:11:235237 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225238 request2.load_flags = 0;
5239
bncce36dca22015-04-21 22:11:235240 // http://www.example.org/
danakj1fd259a02016-04-16 03:17:095241 std::unique_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:235242 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
danakj1fd259a02016-04-16 03:17:095243 std::unique_ptr<SpdySerializedFrame> get1(
bnc38dcd392016-02-09 23:19:495244 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
danakj1fd259a02016-04-16 03:17:095245 std::unique_ptr<SpdySerializedFrame> get_resp1(
[email protected]23e482282013-06-14 16:08:025246 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:095247 std::unique_ptr<SpdySerializedFrame> body1(
[email protected]23e482282013-06-14 16:08:025248 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385249 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225250
bncce36dca22015-04-21 22:11:235251 // http://mail.example.org/
danakj1fd259a02016-04-16 03:17:095252 std::unique_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:235253 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
danakj1fd259a02016-04-16 03:17:095254 std::unique_ptr<SpdySerializedFrame> get2(
bnc38dcd392016-02-09 23:19:495255 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, true));
danakj1fd259a02016-04-16 03:17:095256 std::unique_ptr<SpdySerializedFrame> get_resp2(
[email protected]23e482282013-06-14 16:08:025257 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:095258 std::unique_ptr<SpdySerializedFrame> body2(
[email protected]23e482282013-06-14 16:08:025259 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225260
5261 MockWrite spdy_writes[] = {
5262 CreateMockWrite(*get1, 0),
5263 CreateMockWrite(*get2, 3),
5264 };
5265
5266 MockRead spdy_reads[] = {
5267 CreateMockRead(*get_resp1, 1, ASYNC),
5268 CreateMockRead(*body1, 2, ASYNC),
5269 CreateMockRead(*get_resp2, 4, ASYNC),
5270 CreateMockRead(*body2, 5, ASYNC),
5271 MockRead(ASYNC, 0, 6),
5272 };
5273
mmenke11eb5152015-06-09 14:50:505274 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5275 arraysize(spdy_writes));
5276 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225277
5278 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:385279 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:505280 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225281
5282 TestCompletionCallback callback;
5283
danakj1fd259a02016-04-16 03:17:095284 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505285 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225286 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505287 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225288
5289 LoadTimingInfo load_timing_info;
5290 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5291 TestLoadTimingNotReused(load_timing_info,
5292 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5293
5294 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525295 ASSERT_TRUE(response);
5296 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025297 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225298
5299 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295300 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505301 rv = trans->Read(buf.get(), 256, callback.callback());
5302 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225303 // Delete the first request, so the second one can reuse the socket.
5304 trans.reset();
5305
danakj1fd259a02016-04-16 03:17:095306 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:505307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225308 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505309 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225310
5311 LoadTimingInfo load_timing_info2;
5312 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5313 TestLoadTimingReused(load_timing_info2);
5314
5315 // The requests should have the same ID.
5316 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5317
mmenke11eb5152015-06-09 14:50:505318 rv = trans2->Read(buf.get(), 256, callback.callback());
5319 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225320}
5321
[email protected]2df19bb2010-08-25 20:13:465322// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:025323TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465324 HttpRequestInfo request;
5325 request.method = "GET";
bncce36dca22015-04-21 22:11:235326 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465327 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295328 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465329
[email protected]79cb5c12011-09-12 13:12:045330 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035331 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515332 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075333 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095334 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275335
[email protected]2df19bb2010-08-25 20:13:465336 // Since we have proxy, should use full url
5337 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235338 MockWrite(
5339 "GET http://www.example.org/ HTTP/1.1\r\n"
5340 "Host: www.example.org\r\n"
5341 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465342
bncce36dca22015-04-21 22:11:235343 // After calling trans->RestartWithAuth(), this is the request we should
5344 // be issuing -- the final header line contains the credentials.
5345 MockWrite(
5346 "GET http://www.example.org/ HTTP/1.1\r\n"
5347 "Host: www.example.org\r\n"
5348 "Proxy-Connection: keep-alive\r\n"
5349 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465350 };
5351
5352 // The proxy responds to the GET with a 407, using a persistent
5353 // connection.
5354 MockRead data_reads1[] = {
5355 // No credentials.
5356 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5357 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5358 MockRead("Proxy-Connection: keep-alive\r\n"),
5359 MockRead("Content-Length: 0\r\n\r\n"),
5360
5361 MockRead("HTTP/1.1 200 OK\r\n"),
5362 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5363 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065364 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465365 };
5366
5367 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5368 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075369 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065370 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075371 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465372
[email protected]49639fa2011-12-20 23:22:415373 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465374
danakj1fd259a02016-04-16 03:17:095375 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505376 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505377
[email protected]49639fa2011-12-20 23:22:415378 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:465379 EXPECT_EQ(ERR_IO_PENDING, rv);
5380
5381 rv = callback1.WaitForResult();
5382 EXPECT_EQ(OK, rv);
5383
[email protected]58e32bb2013-01-21 18:23:255384 LoadTimingInfo load_timing_info;
5385 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5386 TestLoadTimingNotReused(load_timing_info,
5387 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5388
[email protected]2df19bb2010-08-25 20:13:465389 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525390 ASSERT_TRUE(response);
5391 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465392 EXPECT_EQ(407, response->headers->response_code());
5393 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:045394 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465395
[email protected]49639fa2011-12-20 23:22:415396 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465397
[email protected]49639fa2011-12-20 23:22:415398 rv = trans->RestartWithAuth(
5399 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:465400 EXPECT_EQ(ERR_IO_PENDING, rv);
5401
5402 rv = callback2.WaitForResult();
5403 EXPECT_EQ(OK, rv);
5404
[email protected]58e32bb2013-01-21 18:23:255405 load_timing_info = LoadTimingInfo();
5406 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5407 // Retrying with HTTP AUTH is considered to be reusing a socket.
5408 TestLoadTimingReused(load_timing_info);
5409
[email protected]2df19bb2010-08-25 20:13:465410 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525411 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465412
5413 EXPECT_TRUE(response->headers->IsKeepAlive());
5414 EXPECT_EQ(200, response->headers->response_code());
5415 EXPECT_EQ(100, response->headers->GetContentLength());
5416 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5417
5418 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525419 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465420}
5421
[email protected]23e482282013-06-14 16:08:025422void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085423 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425424 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085425 request.method = "GET";
bncce36dca22015-04-21 22:11:235426 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085427 request.load_flags = 0;
5428
[email protected]cb9bf6ca2011-01-28 13:15:275429 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035430 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095431 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275432
[email protected]c744cf22009-02-27 07:28:085433 // Since we have proxy, should try to establish tunnel.
5434 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175435 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5436 "Host: www.example.org:443\r\n"
5437 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085438 };
5439
5440 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235441 status, MockRead("Content-Length: 10\r\n\r\n"),
5442 // No response body because the test stops reading here.
5443 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085444 };
5445
[email protected]31a2bfe2010-02-09 08:03:395446 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5447 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075448 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085449
[email protected]49639fa2011-12-20 23:22:415450 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085451
danakj1fd259a02016-04-16 03:17:095452 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505453 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505454
[email protected]49639fa2011-12-20 23:22:415455 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425456 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:085457
5458 rv = callback.WaitForResult();
5459 EXPECT_EQ(expected_status, rv);
5460}
5461
[email protected]23e482282013-06-14 16:08:025462void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235463 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085464 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425465 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085466}
5467
[email protected]23e482282013-06-14 16:08:025468TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085469 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5470}
5471
[email protected]23e482282013-06-14 16:08:025472TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085473 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5474}
5475
[email protected]23e482282013-06-14 16:08:025476TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085477 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5478}
5479
[email protected]23e482282013-06-14 16:08:025480TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085481 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5482}
5483
[email protected]23e482282013-06-14 16:08:025484TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085485 ConnectStatusHelper(
5486 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5487}
5488
[email protected]23e482282013-06-14 16:08:025489TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085490 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5491}
5492
[email protected]23e482282013-06-14 16:08:025493TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085494 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5495}
5496
[email protected]23e482282013-06-14 16:08:025497TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085498 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5499}
5500
[email protected]23e482282013-06-14 16:08:025501TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085502 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5503}
5504
[email protected]23e482282013-06-14 16:08:025505TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085506 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5507}
5508
[email protected]23e482282013-06-14 16:08:025509TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085510 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5511}
5512
[email protected]23e482282013-06-14 16:08:025513TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085514 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5515}
5516
[email protected]23e482282013-06-14 16:08:025517TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085518 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5519}
5520
[email protected]23e482282013-06-14 16:08:025521TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085522 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5523}
5524
[email protected]23e482282013-06-14 16:08:025525TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085526 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5527}
5528
[email protected]23e482282013-06-14 16:08:025529TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085530 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5531}
5532
[email protected]0a17aab32014-04-24 03:32:375533TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
5534 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5535}
5536
[email protected]23e482282013-06-14 16:08:025537TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085538 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5539}
5540
[email protected]23e482282013-06-14 16:08:025541TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085542 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5543}
5544
[email protected]23e482282013-06-14 16:08:025545TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085546 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5547}
5548
[email protected]23e482282013-06-14 16:08:025549TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085550 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5551}
5552
[email protected]23e482282013-06-14 16:08:025553TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085554 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5555}
5556
[email protected]23e482282013-06-14 16:08:025557TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085558 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5559}
5560
[email protected]23e482282013-06-14 16:08:025561TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085562 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5563}
5564
[email protected]23e482282013-06-14 16:08:025565TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085566 ConnectStatusHelperWithExpectedStatus(
5567 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545568 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085569}
5570
[email protected]23e482282013-06-14 16:08:025571TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085572 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5573}
5574
[email protected]23e482282013-06-14 16:08:025575TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085576 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5577}
5578
[email protected]23e482282013-06-14 16:08:025579TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085580 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5581}
5582
[email protected]23e482282013-06-14 16:08:025583TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085584 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5585}
5586
[email protected]23e482282013-06-14 16:08:025587TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085588 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5589}
5590
[email protected]23e482282013-06-14 16:08:025591TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085592 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5593}
5594
[email protected]23e482282013-06-14 16:08:025595TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085596 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5597}
5598
[email protected]23e482282013-06-14 16:08:025599TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085600 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5601}
5602
[email protected]23e482282013-06-14 16:08:025603TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085604 ConnectStatusHelper(
5605 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5606}
5607
[email protected]23e482282013-06-14 16:08:025608TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085609 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5610}
5611
[email protected]23e482282013-06-14 16:08:025612TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085613 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5614}
5615
[email protected]23e482282013-06-14 16:08:025616TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085617 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5618}
5619
[email protected]23e482282013-06-14 16:08:025620TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085621 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5622}
5623
[email protected]23e482282013-06-14 16:08:025624TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085625 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5626}
5627
[email protected]23e482282013-06-14 16:08:025628TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085629 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5630}
5631
[email protected]23e482282013-06-14 16:08:025632TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085633 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5634}
5635
[email protected]038e9a32008-10-08 22:40:165636// Test the flow when both the proxy server AND origin server require
5637// authentication. Again, this uses basic auth for both since that is
5638// the simplest to mock.
[email protected]23e482282013-06-14 16:08:025639TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275640 HttpRequestInfo request;
5641 request.method = "GET";
bncce36dca22015-04-21 22:11:235642 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275643 request.load_flags = 0;
5644
[email protected]038e9a32008-10-08 22:40:165645 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035646 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075648
danakj1fd259a02016-04-16 03:17:095649 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415650 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:165651
[email protected]f9ee6b52008-11-08 06:46:235652 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235653 MockWrite(
5654 "GET http://www.example.org/ HTTP/1.1\r\n"
5655 "Host: www.example.org\r\n"
5656 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235657 };
5658
[email protected]038e9a32008-10-08 22:40:165659 MockRead data_reads1[] = {
5660 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5661 // Give a couple authenticate options (only the middle one is actually
5662 // supported).
[email protected]22927ad2009-09-21 19:56:195663 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165664 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5665 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5666 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5667 // Large content-length -- won't matter, as connection will be reset.
5668 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065669 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165670 };
5671
5672 // After calling trans->RestartWithAuth() the first time, this is the
5673 // request we should be issuing -- the final header line contains the
5674 // proxy's credentials.
5675 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235676 MockWrite(
5677 "GET http://www.example.org/ HTTP/1.1\r\n"
5678 "Host: www.example.org\r\n"
5679 "Proxy-Connection: keep-alive\r\n"
5680 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165681 };
5682
5683 // Now the proxy server lets the request pass through to origin server.
5684 // The origin server responds with a 401.
5685 MockRead data_reads2[] = {
5686 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5687 // Note: We are using the same realm-name as the proxy server. This is
5688 // completely valid, as realms are unique across hosts.
5689 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5690 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5691 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065692 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165693 };
5694
5695 // After calling trans->RestartWithAuth() the second time, we should send
5696 // the credentials for both the proxy and origin server.
5697 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235698 MockWrite(
5699 "GET http://www.example.org/ HTTP/1.1\r\n"
5700 "Host: www.example.org\r\n"
5701 "Proxy-Connection: keep-alive\r\n"
5702 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5703 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165704 };
5705
5706 // Lastly we get the desired content.
5707 MockRead data_reads3[] = {
5708 MockRead("HTTP/1.0 200 OK\r\n"),
5709 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5710 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065711 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165712 };
5713
[email protected]31a2bfe2010-02-09 08:03:395714 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5715 data_writes1, arraysize(data_writes1));
5716 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5717 data_writes2, arraysize(data_writes2));
5718 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5719 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075720 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5721 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5722 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165723
[email protected]49639fa2011-12-20 23:22:415724 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165725
[email protected]49639fa2011-12-20 23:22:415726 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425727 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165728
5729 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425730 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165731
[email protected]1c773ea12009-04-28 19:58:425732 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525733 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045734 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165735
[email protected]49639fa2011-12-20 23:22:415736 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165737
[email protected]49639fa2011-12-20 23:22:415738 rv = trans->RestartWithAuth(
5739 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425740 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165741
5742 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425743 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165744
5745 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525746 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045747 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165748
[email protected]49639fa2011-12-20 23:22:415749 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165750
[email protected]49639fa2011-12-20 23:22:415751 rv = trans->RestartWithAuth(
5752 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425753 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165754
5755 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425756 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165757
5758 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525759 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165760 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165761}
[email protected]4ddaf2502008-10-23 18:26:195762
[email protected]ea9dc9a2009-09-05 00:43:325763// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5764// can't hook into its internals to cause it to generate predictable NTLM
5765// authorization headers.
5766#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295767// The NTLM authentication unit tests were generated by capturing the HTTP
5768// requests and responses using Fiddler 2 and inspecting the generated random
5769// bytes in the debugger.
5770
5771// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:025772TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425773 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245774 request.method = "GET";
5775 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545776
5777 // Ensure load is not disrupted by flags which suppress behaviour specific
5778 // to other auth schemes.
5779 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245780
[email protected]cb9bf6ca2011-01-28 13:15:275781 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5782 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095783 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275784
[email protected]3f918782009-02-28 01:29:245785 MockWrite data_writes1[] = {
5786 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5787 "Host: 172.22.68.17\r\n"
5788 "Connection: keep-alive\r\n\r\n"),
5789 };
5790
5791 MockRead data_reads1[] = {
5792 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045793 // Negotiate and NTLM are often requested together. However, we only want
5794 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5795 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245796 MockRead("WWW-Authenticate: NTLM\r\n"),
5797 MockRead("Connection: close\r\n"),
5798 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365799 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245800 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065801 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245802 };
5803
5804 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225805 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:245806 // request we should be issuing -- the final header line contains a Type
5807 // 1 message.
5808 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5809 "Host: 172.22.68.17\r\n"
5810 "Connection: keep-alive\r\n"
5811 "Authorization: NTLM "
5812 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5813
5814 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5815 // (the credentials for the origin server). The second request continues
5816 // on the same connection.
5817 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5818 "Host: 172.22.68.17\r\n"
5819 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:295820 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5821 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5822 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5823 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5824 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245825 };
5826
5827 MockRead data_reads2[] = {
5828 // The origin server responds with a Type 2 message.
5829 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5830 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295831 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245832 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5833 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5834 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5835 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5836 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5837 "BtAAAAAAA=\r\n"),
5838 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365839 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245840 MockRead("You are not authorized to view this page\r\n"),
5841
5842 // Lastly we get the desired content.
5843 MockRead("HTTP/1.1 200 OK\r\n"),
5844 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5845 MockRead("Content-Length: 13\r\n\r\n"),
5846 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065847 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245848 };
5849
[email protected]31a2bfe2010-02-09 08:03:395850 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5851 data_writes1, arraysize(data_writes1));
5852 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5853 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075854 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5855 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245856
[email protected]49639fa2011-12-20 23:22:415857 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245858
danakj1fd259a02016-04-16 03:17:095859 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505860 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505861
[email protected]49639fa2011-12-20 23:22:415862 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425863 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245864
5865 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425866 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245867
[email protected]0757e7702009-03-27 04:00:225868 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5869
[email protected]1c773ea12009-04-28 19:58:425870 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525871 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045872 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245873
[email protected]49639fa2011-12-20 23:22:415874 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255875
[email protected]f3cf9802011-10-28 18:44:585876 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415877 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:255878 EXPECT_EQ(ERR_IO_PENDING, rv);
5879
5880 rv = callback2.WaitForResult();
5881 EXPECT_EQ(OK, rv);
5882
5883 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5884
5885 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525886 ASSERT_TRUE(response);
5887 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255888
[email protected]49639fa2011-12-20 23:22:415889 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245890
[email protected]49639fa2011-12-20 23:22:415891 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425892 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245893
[email protected]0757e7702009-03-27 04:00:225894 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425895 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245896
5897 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525898 ASSERT_TRUE(response);
5899 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245900 EXPECT_EQ(13, response->headers->GetContentLength());
5901}
5902
[email protected]385a4672009-03-11 22:21:295903// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:025904TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425905 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295906 request.method = "GET";
5907 request.url = GURL("http://172.22.68.17/kids/login.aspx");
5908 request.load_flags = 0;
5909
[email protected]cb9bf6ca2011-01-28 13:15:275910 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5911 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095912 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275913
[email protected]385a4672009-03-11 22:21:295914 MockWrite data_writes1[] = {
5915 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5916 "Host: 172.22.68.17\r\n"
5917 "Connection: keep-alive\r\n\r\n"),
5918 };
5919
5920 MockRead data_reads1[] = {
5921 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045922 // Negotiate and NTLM are often requested together. However, we only want
5923 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5924 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:295925 MockRead("WWW-Authenticate: NTLM\r\n"),
5926 MockRead("Connection: close\r\n"),
5927 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365928 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295929 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065930 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295931 };
5932
5933 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225934 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295935 // request we should be issuing -- the final header line contains a Type
5936 // 1 message.
5937 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5938 "Host: 172.22.68.17\r\n"
5939 "Connection: keep-alive\r\n"
5940 "Authorization: NTLM "
5941 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5942
5943 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5944 // (the credentials for the origin server). The second request continues
5945 // on the same connection.
5946 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5947 "Host: 172.22.68.17\r\n"
5948 "Connection: keep-alive\r\n"
5949 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5950 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5951 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
5952 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
5953 "4Ww7b7E=\r\n\r\n"),
5954 };
5955
5956 MockRead data_reads2[] = {
5957 // The origin server responds with a Type 2 message.
5958 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5959 MockRead("WWW-Authenticate: NTLM "
5960 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
5961 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5962 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5963 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5964 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5965 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5966 "BtAAAAAAA=\r\n"),
5967 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365968 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295969 MockRead("You are not authorized to view this page\r\n"),
5970
5971 // Wrong password.
5972 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:295973 MockRead("WWW-Authenticate: NTLM\r\n"),
5974 MockRead("Connection: close\r\n"),
5975 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365976 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295977 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065978 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295979 };
5980
5981 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:225982 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295983 // request we should be issuing -- the final header line contains a Type
5984 // 1 message.
5985 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5986 "Host: 172.22.68.17\r\n"
5987 "Connection: keep-alive\r\n"
5988 "Authorization: NTLM "
5989 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5990
5991 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5992 // (the credentials for the origin server). The second request continues
5993 // on the same connection.
5994 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5995 "Host: 172.22.68.17\r\n"
5996 "Connection: keep-alive\r\n"
5997 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5998 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5999 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6000 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6001 "+4MUm7c=\r\n\r\n"),
6002 };
6003
6004 MockRead data_reads3[] = {
6005 // The origin server responds with a Type 2 message.
6006 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6007 MockRead("WWW-Authenticate: NTLM "
6008 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6009 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6010 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6011 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6012 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6013 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6014 "BtAAAAAAA=\r\n"),
6015 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366016 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296017 MockRead("You are not authorized to view this page\r\n"),
6018
6019 // Lastly we get the desired content.
6020 MockRead("HTTP/1.1 200 OK\r\n"),
6021 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6022 MockRead("Content-Length: 13\r\n\r\n"),
6023 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066024 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296025 };
6026
[email protected]31a2bfe2010-02-09 08:03:396027 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6028 data_writes1, arraysize(data_writes1));
6029 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6030 data_writes2, arraysize(data_writes2));
6031 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6032 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076033 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6034 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6035 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296036
[email protected]49639fa2011-12-20 23:22:416037 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296038
danakj1fd259a02016-04-16 03:17:096039 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506040 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:506041
[email protected]49639fa2011-12-20 23:22:416042 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426043 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:296044
6045 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426046 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:296047
[email protected]0757e7702009-03-27 04:00:226048 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296049
[email protected]1c773ea12009-04-28 19:58:426050 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526051 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046052 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296053
[email protected]49639fa2011-12-20 23:22:416054 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296055
[email protected]0757e7702009-03-27 04:00:226056 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:586057 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:416058 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426059 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:296060
[email protected]10af5fe72011-01-31 16:17:256061 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426062 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:296063
[email protected]0757e7702009-03-27 04:00:226064 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416065 TestCompletionCallback callback3;
6066 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426067 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:256068 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426069 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226070 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6071
6072 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526073 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046074 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226075
[email protected]49639fa2011-12-20 23:22:416076 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226077
6078 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:586079 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:416080 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:256081 EXPECT_EQ(ERR_IO_PENDING, rv);
6082
6083 rv = callback4.WaitForResult();
6084 EXPECT_EQ(OK, rv);
6085
6086 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6087
[email protected]49639fa2011-12-20 23:22:416088 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256089
6090 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:416091 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:426092 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226093
6094 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426095 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226096
[email protected]385a4672009-03-11 22:21:296097 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526098 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296099 EXPECT_EQ(13, response->headers->GetContentLength());
6100}
[email protected]ea9dc9a2009-09-05 00:43:326101#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296102
[email protected]4ddaf2502008-10-23 18:26:196103// Test reading a server response which has only headers, and no body.
6104// After some maximum number of bytes is consumed, the transaction should
6105// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:026106TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426107 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196108 request.method = "GET";
bncce36dca22015-04-21 22:11:236109 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196110 request.load_flags = 0;
6111
danakj1fd259a02016-04-16 03:17:096112 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6113 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416114 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276115
[email protected]b75b7b2f2009-10-06 00:54:536116 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436117 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536118 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196119
6120 MockRead data_reads[] = {
6121 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066122 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196123 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066124 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196125 };
[email protected]31a2bfe2010-02-09 08:03:396126 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076127 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196128
[email protected]49639fa2011-12-20 23:22:416129 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196130
[email protected]49639fa2011-12-20 23:22:416131 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426132 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:196133
6134 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426135 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:196136}
[email protected]f4e426b2008-11-05 00:24:496137
6138// Make sure that we don't try to reuse a TCPClientSocket when failing to
6139// establish tunnel.
6140// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:026141TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:236142 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276143 HttpRequestInfo request;
6144 request.method = "GET";
bncce36dca22015-04-21 22:11:236145 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276146 request.load_flags = 0;
6147
[email protected]f4e426b2008-11-05 00:24:496148 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036149 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016150
danakj1fd259a02016-04-16 03:17:096151 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496152
danakj1fd259a02016-04-16 03:17:096153 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506154 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:496155
[email protected]f4e426b2008-11-05 00:24:496156 // Since we have proxy, should try to establish tunnel.
6157 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176158 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6159 "Host: www.example.org:443\r\n"
6160 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496161 };
6162
[email protected]77848d12008-11-14 00:00:226163 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496164 // connection. Usually a proxy would return 501 (not implemented),
6165 // or 200 (tunnel established).
6166 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236167 MockRead("HTTP/1.1 404 Not Found\r\n"),
6168 MockRead("Content-Length: 10\r\n\r\n"),
6169 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496170 };
6171
[email protected]31a2bfe2010-02-09 08:03:396172 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6173 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076174 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496175
[email protected]49639fa2011-12-20 23:22:416176 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496177
[email protected]49639fa2011-12-20 23:22:416178 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426179 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:496180
6181 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426182 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:496183
[email protected]b4404c02009-04-10 16:38:526184 // Empty the current queue. This is necessary because idle sockets are
6185 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556186 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526187
[email protected]f4e426b2008-11-05 00:24:496188 // We now check to make sure the TCPClientSocket was not added back to
6189 // the pool.
[email protected]90499482013-06-01 00:39:506190 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496191 trans.reset();
fdoray92e35a72016-06-10 15:54:556192 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496193 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506194 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496195}
[email protected]372d34a2008-11-05 21:30:516196
[email protected]1b157c02009-04-21 01:55:406197// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:026198TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426199 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406200 request.method = "GET";
bncce36dca22015-04-21 22:11:236201 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406202 request.load_flags = 0;
6203
danakj1fd259a02016-04-16 03:17:096204 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276205
danakj1fd259a02016-04-16 03:17:096206 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506207 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276208
[email protected]1b157c02009-04-21 01:55:406209 MockRead data_reads[] = {
6210 // A part of the response body is received with the response headers.
6211 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6212 // The rest of the response body is received in two parts.
6213 MockRead("lo"),
6214 MockRead(" world"),
6215 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066216 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406217 };
6218
[email protected]31a2bfe2010-02-09 08:03:396219 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076220 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406221
[email protected]49639fa2011-12-20 23:22:416222 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406223
[email protected]49639fa2011-12-20 23:22:416224 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426225 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:406226
6227 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426228 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:406229
[email protected]1c773ea12009-04-28 19:58:426230 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526231 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406232
wezca1070932016-05-26 20:30:526233 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406234 std::string status_line = response->headers->GetStatusLine();
6235 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6236
[email protected]90499482013-06-01 00:39:506237 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406238
6239 std::string response_data;
6240 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426241 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:406242 EXPECT_EQ("hello world", response_data);
6243
6244 // Empty the current queue. This is necessary because idle sockets are
6245 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556246 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406247
6248 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506249 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406250}
6251
[email protected]76a505b2010-08-25 06:23:006252// Make sure that we recycle a SSL socket after reading all of the response
6253// body.
[email protected]23e482282013-06-14 16:08:026254TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006255 HttpRequestInfo request;
6256 request.method = "GET";
bncce36dca22015-04-21 22:11:236257 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006258 request.load_flags = 0;
6259
6260 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236261 MockWrite(
6262 "GET / HTTP/1.1\r\n"
6263 "Host: www.example.org\r\n"
6264 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006265 };
6266
6267 MockRead data_reads[] = {
6268 MockRead("HTTP/1.1 200 OK\r\n"),
6269 MockRead("Content-Length: 11\r\n\r\n"),
6270 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066271 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006272 };
6273
[email protected]8ddf8322012-02-23 18:08:066274 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006276
6277 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6278 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076279 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006280
[email protected]49639fa2011-12-20 23:22:416281 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006282
danakj1fd259a02016-04-16 03:17:096283 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6284 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506285 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006286
[email protected]49639fa2011-12-20 23:22:416287 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006288
6289 EXPECT_EQ(ERR_IO_PENDING, rv);
6290 EXPECT_EQ(OK, callback.WaitForResult());
6291
6292 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526293 ASSERT_TRUE(response);
6294 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006295 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6296
[email protected]90499482013-06-01 00:39:506297 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006298
6299 std::string response_data;
6300 rv = ReadTransaction(trans.get(), &response_data);
6301 EXPECT_EQ(OK, rv);
6302 EXPECT_EQ("hello world", response_data);
6303
6304 // Empty the current queue. This is necessary because idle sockets are
6305 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556306 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006307
6308 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506309 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006310}
6311
6312// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6313// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:026314TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006315 HttpRequestInfo request;
6316 request.method = "GET";
bncce36dca22015-04-21 22:11:236317 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006318 request.load_flags = 0;
6319
6320 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236321 MockWrite(
6322 "GET / HTTP/1.1\r\n"
6323 "Host: www.example.org\r\n"
6324 "Connection: keep-alive\r\n\r\n"),
6325 MockWrite(
6326 "GET / HTTP/1.1\r\n"
6327 "Host: www.example.org\r\n"
6328 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006329 };
6330
6331 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426332 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6333 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006334
[email protected]8ddf8322012-02-23 18:08:066335 SSLSocketDataProvider ssl(ASYNC, OK);
6336 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076337 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6338 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006339
6340 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6341 data_writes, arraysize(data_writes));
6342 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6343 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076344 session_deps_.socket_factory->AddSocketDataProvider(&data);
6345 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006346
[email protected]49639fa2011-12-20 23:22:416347 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006348
danakj1fd259a02016-04-16 03:17:096349 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6350 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506351 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006352
[email protected]49639fa2011-12-20 23:22:416353 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006354
6355 EXPECT_EQ(ERR_IO_PENDING, rv);
6356 EXPECT_EQ(OK, callback.WaitForResult());
6357
6358 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526359 ASSERT_TRUE(response);
6360 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006361 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6362
[email protected]90499482013-06-01 00:39:506363 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006364
6365 std::string response_data;
6366 rv = ReadTransaction(trans.get(), &response_data);
6367 EXPECT_EQ(OK, rv);
6368 EXPECT_EQ("hello world", response_data);
6369
6370 // Empty the current queue. This is necessary because idle sockets are
6371 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556372 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006373
6374 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506375 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006376
6377 // Now start the second transaction, which should reuse the previous socket.
6378
[email protected]90499482013-06-01 00:39:506379 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006380
[email protected]49639fa2011-12-20 23:22:416381 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006382
6383 EXPECT_EQ(ERR_IO_PENDING, rv);
6384 EXPECT_EQ(OK, callback.WaitForResult());
6385
6386 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526387 ASSERT_TRUE(response);
6388 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006389 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6390
[email protected]90499482013-06-01 00:39:506391 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006392
6393 rv = ReadTransaction(trans.get(), &response_data);
6394 EXPECT_EQ(OK, rv);
6395 EXPECT_EQ("hello world", response_data);
6396
6397 // Empty the current queue. This is necessary because idle sockets are
6398 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556399 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006400
6401 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506402 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006403}
6404
[email protected]b4404c02009-04-10 16:38:526405// Make sure that we recycle a socket after a zero-length response.
6406// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:026407TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426408 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526409 request.method = "GET";
bncce36dca22015-04-21 22:11:236410 request.url = GURL(
6411 "http://www.example.org/csi?v=3&s=web&action=&"
6412 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6413 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6414 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526415 request.load_flags = 0;
6416
danakj1fd259a02016-04-16 03:17:096417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276418
[email protected]b4404c02009-04-10 16:38:526419 MockRead data_reads[] = {
6420 MockRead("HTTP/1.1 204 No Content\r\n"
6421 "Content-Length: 0\r\n"
6422 "Content-Type: text/html\r\n\r\n"),
6423 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066424 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526425 };
6426
[email protected]31a2bfe2010-02-09 08:03:396427 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076428 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526429
mmenkecc2298e2015-12-07 18:20:186430 // Transaction must be created after the MockReads, so it's destroyed before
6431 // them.
danakj1fd259a02016-04-16 03:17:096432 std::unique_ptr<HttpTransaction> trans(
mmenkecc2298e2015-12-07 18:20:186433 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6434
[email protected]49639fa2011-12-20 23:22:416435 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526436
[email protected]49639fa2011-12-20 23:22:416437 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426438 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:526439
6440 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426441 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:526442
[email protected]1c773ea12009-04-28 19:58:426443 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526444 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526445
wezca1070932016-05-26 20:30:526446 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526447 std::string status_line = response->headers->GetStatusLine();
6448 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6449
[email protected]90499482013-06-01 00:39:506450 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526451
6452 std::string response_data;
6453 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426454 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:526455 EXPECT_EQ("", response_data);
6456
6457 // Empty the current queue. This is necessary because idle sockets are
6458 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556459 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526460
6461 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506462 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526463}
6464
[email protected]23e482282013-06-14 16:08:026465TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096466 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226467 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:096468 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:226469 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276470
[email protected]1c773ea12009-04-28 19:58:426471 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516472 // Transaction 1: a GET request that succeeds. The socket is recycled
6473 // after use.
6474 request[0].method = "GET";
6475 request[0].url = GURL("http://www.google.com/");
6476 request[0].load_flags = 0;
6477 // Transaction 2: a POST request. Reuses the socket kept alive from
6478 // transaction 1. The first attempts fails when writing the POST data.
6479 // This causes the transaction to retry with a new socket. The second
6480 // attempt succeeds.
6481 request[1].method = "POST";
6482 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276483 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516484 request[1].load_flags = 0;
6485
danakj1fd259a02016-04-16 03:17:096486 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516487
6488 // The first socket is used for transaction 1 and the first attempt of
6489 // transaction 2.
6490
6491 // The response of transaction 1.
6492 MockRead data_reads1[] = {
6493 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6494 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066495 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516496 };
6497 // The mock write results of transaction 1 and the first attempt of
6498 // transaction 2.
6499 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066500 MockWrite(SYNCHRONOUS, 64), // GET
6501 MockWrite(SYNCHRONOUS, 93), // POST
6502 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516503 };
[email protected]31a2bfe2010-02-09 08:03:396504 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6505 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516506
6507 // The second socket is used for the second attempt of transaction 2.
6508
6509 // The response of transaction 2.
6510 MockRead data_reads2[] = {
6511 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6512 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066513 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516514 };
6515 // The mock write results of the second attempt of transaction 2.
6516 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066517 MockWrite(SYNCHRONOUS, 93), // POST
6518 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516519 };
[email protected]31a2bfe2010-02-09 08:03:396520 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6521 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516522
[email protected]bb88e1d32013-05-03 23:11:076523 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6524 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516525
thestig9d3bb0c2015-01-24 00:49:516526 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516527 "hello world", "welcome"
6528 };
6529
6530 for (int i = 0; i < 2; ++i) {
danakj1fd259a02016-04-16 03:17:096531 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506532 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:516533
[email protected]49639fa2011-12-20 23:22:416534 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516535
[email protected]49639fa2011-12-20 23:22:416536 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426537 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:516538
6539 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426540 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516541
[email protected]1c773ea12009-04-28 19:58:426542 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526543 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516544
wezca1070932016-05-26 20:30:526545 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516546 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6547
6548 std::string response_data;
6549 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426550 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516551 EXPECT_EQ(kExpectedResponseData[i], response_data);
6552 }
6553}
[email protected]f9ee6b52008-11-08 06:46:236554
6555// Test the request-challenge-retry sequence for basic auth when there is
6556// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166557// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:026558TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426559 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236560 request.method = "GET";
bncce36dca22015-04-21 22:11:236561 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416562 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296563
danakj1fd259a02016-04-16 03:17:096564 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6565 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416566 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276567
[email protected]a97cca42009-08-14 01:00:296568 // The password contains an escaped character -- for this test to pass it
6569 // will need to be unescaped by HttpNetworkTransaction.
6570 EXPECT_EQ("b%40r", request.url.password());
6571
[email protected]f9ee6b52008-11-08 06:46:236572 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236573 MockWrite(
6574 "GET / HTTP/1.1\r\n"
6575 "Host: www.example.org\r\n"
6576 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236577 };
6578
6579 MockRead data_reads1[] = {
6580 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6581 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6582 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066583 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236584 };
6585
[email protected]2262e3a2012-05-22 16:08:166586 // After the challenge above, the transaction will be restarted using the
6587 // identity from the url (foo, b@r) to answer the challenge.
6588 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236589 MockWrite(
6590 "GET / HTTP/1.1\r\n"
6591 "Host: www.example.org\r\n"
6592 "Connection: keep-alive\r\n"
6593 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166594 };
6595
6596 MockRead data_reads2[] = {
6597 MockRead("HTTP/1.0 200 OK\r\n"),
6598 MockRead("Content-Length: 100\r\n\r\n"),
6599 MockRead(SYNCHRONOUS, OK),
6600 };
6601
[email protected]31a2bfe2010-02-09 08:03:396602 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6603 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166604 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6605 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076606 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6607 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236608
[email protected]49639fa2011-12-20 23:22:416609 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:416610 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426611 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236612 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426613 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:166614 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6615
6616 TestCompletionCallback callback2;
6617 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6618 EXPECT_EQ(ERR_IO_PENDING, rv);
6619 rv = callback2.WaitForResult();
6620 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226621 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6622
[email protected]2262e3a2012-05-22 16:08:166623 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526624 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166625
6626 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526627 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166628
6629 EXPECT_EQ(100, response->headers->GetContentLength());
6630
6631 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556632 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166633}
6634
6635// Test the request-challenge-retry sequence for basic auth when there is an
6636// incorrect identity in the URL. The identity from the URL should be used only
6637// once.
[email protected]23e482282013-06-14 16:08:026638TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166639 HttpRequestInfo request;
6640 request.method = "GET";
6641 // Note: the URL has a username:password in it. The password "baz" is
6642 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236643 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166644
6645 request.load_flags = LOAD_NORMAL;
6646
danakj1fd259a02016-04-16 03:17:096647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6648 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416649 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:166650
6651 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236652 MockWrite(
6653 "GET / HTTP/1.1\r\n"
6654 "Host: www.example.org\r\n"
6655 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166656 };
6657
6658 MockRead data_reads1[] = {
6659 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6660 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6661 MockRead("Content-Length: 10\r\n\r\n"),
6662 MockRead(SYNCHRONOUS, ERR_FAILED),
6663 };
6664
6665 // After the challenge above, the transaction will be restarted using the
6666 // identity from the url (foo, baz) to answer the challenge.
6667 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236668 MockWrite(
6669 "GET / HTTP/1.1\r\n"
6670 "Host: www.example.org\r\n"
6671 "Connection: keep-alive\r\n"
6672 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166673 };
6674
6675 MockRead data_reads2[] = {
6676 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6677 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6678 MockRead("Content-Length: 10\r\n\r\n"),
6679 MockRead(SYNCHRONOUS, ERR_FAILED),
6680 };
6681
6682 // After the challenge above, the transaction will be restarted using the
6683 // identity supplied by the user (foo, bar) to answer the challenge.
6684 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236685 MockWrite(
6686 "GET / HTTP/1.1\r\n"
6687 "Host: www.example.org\r\n"
6688 "Connection: keep-alive\r\n"
6689 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166690 };
6691
6692 MockRead data_reads3[] = {
6693 MockRead("HTTP/1.0 200 OK\r\n"),
6694 MockRead("Content-Length: 100\r\n\r\n"),
6695 MockRead(SYNCHRONOUS, OK),
6696 };
6697
6698 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6699 data_writes1, arraysize(data_writes1));
6700 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6701 data_writes2, arraysize(data_writes2));
6702 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6703 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076704 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6705 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6706 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166707
6708 TestCompletionCallback callback1;
6709
6710 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6711 EXPECT_EQ(ERR_IO_PENDING, rv);
6712
6713 rv = callback1.WaitForResult();
6714 EXPECT_EQ(OK, rv);
6715
6716 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6717 TestCompletionCallback callback2;
6718 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6719 EXPECT_EQ(ERR_IO_PENDING, rv);
6720 rv = callback2.WaitForResult();
6721 EXPECT_EQ(OK, rv);
6722 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6723
6724 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526725 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166726 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6727
6728 TestCompletionCallback callback3;
6729 rv = trans->RestartWithAuth(
6730 AuthCredentials(kFoo, kBar), callback3.callback());
6731 EXPECT_EQ(ERR_IO_PENDING, rv);
6732 rv = callback3.WaitForResult();
6733 EXPECT_EQ(OK, rv);
6734 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6735
6736 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526737 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166738
6739 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526740 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166741
6742 EXPECT_EQ(100, response->headers->GetContentLength());
6743
[email protected]ea9dc9a2009-09-05 00:43:326744 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556745 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326746}
6747
[email protected]2217aa22013-10-11 03:03:546748
6749// Test the request-challenge-retry sequence for basic auth when there is a
6750// correct identity in the URL, but its use is being suppressed. The identity
6751// from the URL should never be used.
6752TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
6753 HttpRequestInfo request;
6754 request.method = "GET";
bncce36dca22015-04-21 22:11:236755 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546756 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6757
danakj1fd259a02016-04-16 03:17:096758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6759 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416760 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:546761
6762 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236763 MockWrite(
6764 "GET / HTTP/1.1\r\n"
6765 "Host: www.example.org\r\n"
6766 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546767 };
6768
6769 MockRead data_reads1[] = {
6770 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6771 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6772 MockRead("Content-Length: 10\r\n\r\n"),
6773 MockRead(SYNCHRONOUS, ERR_FAILED),
6774 };
6775
6776 // After the challenge above, the transaction will be restarted using the
6777 // identity supplied by the user, not the one in the URL, to answer the
6778 // challenge.
6779 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236780 MockWrite(
6781 "GET / HTTP/1.1\r\n"
6782 "Host: www.example.org\r\n"
6783 "Connection: keep-alive\r\n"
6784 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546785 };
6786
6787 MockRead data_reads3[] = {
6788 MockRead("HTTP/1.0 200 OK\r\n"),
6789 MockRead("Content-Length: 100\r\n\r\n"),
6790 MockRead(SYNCHRONOUS, OK),
6791 };
6792
6793 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6794 data_writes1, arraysize(data_writes1));
6795 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6796 data_writes3, arraysize(data_writes3));
6797 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6798 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6799
6800 TestCompletionCallback callback1;
6801 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6802 EXPECT_EQ(ERR_IO_PENDING, rv);
6803 rv = callback1.WaitForResult();
6804 EXPECT_EQ(OK, rv);
6805 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6806
6807 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526808 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:546809 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6810
6811 TestCompletionCallback callback3;
6812 rv = trans->RestartWithAuth(
6813 AuthCredentials(kFoo, kBar), callback3.callback());
6814 EXPECT_EQ(ERR_IO_PENDING, rv);
6815 rv = callback3.WaitForResult();
6816 EXPECT_EQ(OK, rv);
6817 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6818
6819 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526820 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:546821
6822 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526823 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:546824 EXPECT_EQ(100, response->headers->GetContentLength());
6825
6826 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556827 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:546828}
6829
[email protected]f9ee6b52008-11-08 06:46:236830// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:026831TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:096832 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:236833
6834 // Transaction 1: authenticate (foo, bar) on MyRealm1
6835 {
[email protected]1c773ea12009-04-28 19:58:426836 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236837 request.method = "GET";
bncce36dca22015-04-21 22:11:236838 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:236839 request.load_flags = 0;
6840
danakj1fd259a02016-04-16 03:17:096841 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506842 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276843
[email protected]f9ee6b52008-11-08 06:46:236844 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236845 MockWrite(
6846 "GET /x/y/z HTTP/1.1\r\n"
6847 "Host: www.example.org\r\n"
6848 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236849 };
6850
6851 MockRead data_reads1[] = {
6852 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6853 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6854 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066855 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236856 };
6857
6858 // Resend with authorization (username=foo, password=bar)
6859 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236860 MockWrite(
6861 "GET /x/y/z HTTP/1.1\r\n"
6862 "Host: www.example.org\r\n"
6863 "Connection: keep-alive\r\n"
6864 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236865 };
6866
6867 // Sever accepts the authorization.
6868 MockRead data_reads2[] = {
6869 MockRead("HTTP/1.0 200 OK\r\n"),
6870 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066871 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236872 };
6873
[email protected]31a2bfe2010-02-09 08:03:396874 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6875 data_writes1, arraysize(data_writes1));
6876 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6877 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076878 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6879 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236880
[email protected]49639fa2011-12-20 23:22:416881 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236882
[email protected]49639fa2011-12-20 23:22:416883 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426884 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236885
6886 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426887 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236888
[email protected]1c773ea12009-04-28 19:58:426889 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526890 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046891 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236892
[email protected]49639fa2011-12-20 23:22:416893 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236894
[email protected]49639fa2011-12-20 23:22:416895 rv = trans->RestartWithAuth(
6896 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426897 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236898
6899 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426900 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236901
6902 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526903 ASSERT_TRUE(response);
6904 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:236905 EXPECT_EQ(100, response->headers->GetContentLength());
6906 }
6907
6908 // ------------------------------------------------------------------------
6909
6910 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
6911 {
[email protected]1c773ea12009-04-28 19:58:426912 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236913 request.method = "GET";
6914 // Note that Transaction 1 was at /x/y/z, so this is in the same
6915 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:236916 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:236917 request.load_flags = 0;
6918
danakj1fd259a02016-04-16 03:17:096919 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506920 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276921
[email protected]f9ee6b52008-11-08 06:46:236922 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236923 MockWrite(
6924 "GET /x/y/a/b HTTP/1.1\r\n"
6925 "Host: www.example.org\r\n"
6926 "Connection: keep-alive\r\n"
6927 // Send preemptive authorization for MyRealm1
6928 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236929 };
6930
6931 // The server didn't like the preemptive authorization, and
6932 // challenges us for a different realm (MyRealm2).
6933 MockRead data_reads1[] = {
6934 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6935 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
6936 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066937 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236938 };
6939
6940 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
6941 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236942 MockWrite(
6943 "GET /x/y/a/b HTTP/1.1\r\n"
6944 "Host: www.example.org\r\n"
6945 "Connection: keep-alive\r\n"
6946 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236947 };
6948
6949 // Sever accepts the authorization.
6950 MockRead data_reads2[] = {
6951 MockRead("HTTP/1.0 200 OK\r\n"),
6952 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066953 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236954 };
6955
[email protected]31a2bfe2010-02-09 08:03:396956 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6957 data_writes1, arraysize(data_writes1));
6958 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6959 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076960 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6961 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236962
[email protected]49639fa2011-12-20 23:22:416963 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236964
[email protected]49639fa2011-12-20 23:22:416965 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426966 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236967
6968 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426969 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236970
[email protected]1c773ea12009-04-28 19:58:426971 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526972 ASSERT_TRUE(response);
6973 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:046974 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:236975 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:046976 response->auth_challenge->challenger.ToString());
6977 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:196978 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:236979
[email protected]49639fa2011-12-20 23:22:416980 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236981
[email protected]49639fa2011-12-20 23:22:416982 rv = trans->RestartWithAuth(
6983 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426984 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236985
6986 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426987 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236988
6989 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526990 ASSERT_TRUE(response);
6991 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:236992 EXPECT_EQ(100, response->headers->GetContentLength());
6993 }
6994
6995 // ------------------------------------------------------------------------
6996
6997 // Transaction 3: Resend a request in MyRealm's protection space --
6998 // succeed with preemptive authorization.
6999 {
[email protected]1c773ea12009-04-28 19:58:427000 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237001 request.method = "GET";
bncce36dca22015-04-21 22:11:237002 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237003 request.load_flags = 0;
7004
danakj1fd259a02016-04-16 03:17:097005 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507006 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277007
[email protected]f9ee6b52008-11-08 06:46:237008 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237009 MockWrite(
7010 "GET /x/y/z2 HTTP/1.1\r\n"
7011 "Host: www.example.org\r\n"
7012 "Connection: keep-alive\r\n"
7013 // The authorization for MyRealm1 gets sent preemptively
7014 // (since the url is in the same protection space)
7015 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237016 };
7017
7018 // Sever accepts the preemptive authorization
7019 MockRead data_reads1[] = {
7020 MockRead("HTTP/1.0 200 OK\r\n"),
7021 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067022 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237023 };
7024
[email protected]31a2bfe2010-02-09 08:03:397025 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7026 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077027 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237028
[email protected]49639fa2011-12-20 23:22:417029 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237030
[email protected]49639fa2011-12-20 23:22:417031 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427032 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237033
7034 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427035 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237036
[email protected]1c773ea12009-04-28 19:58:427037 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527038 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237039
wezca1070932016-05-26 20:30:527040 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237041 EXPECT_EQ(100, response->headers->GetContentLength());
7042 }
7043
7044 // ------------------------------------------------------------------------
7045
7046 // Transaction 4: request another URL in MyRealm (however the
7047 // url is not known to belong to the protection space, so no pre-auth).
7048 {
[email protected]1c773ea12009-04-28 19:58:427049 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237050 request.method = "GET";
bncce36dca22015-04-21 22:11:237051 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237052 request.load_flags = 0;
7053
danakj1fd259a02016-04-16 03:17:097054 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507055 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277056
[email protected]f9ee6b52008-11-08 06:46:237057 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237058 MockWrite(
7059 "GET /x/1 HTTP/1.1\r\n"
7060 "Host: www.example.org\r\n"
7061 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237062 };
7063
7064 MockRead data_reads1[] = {
7065 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7066 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7067 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067068 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237069 };
7070
7071 // Resend with authorization from MyRealm's cache.
7072 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237073 MockWrite(
7074 "GET /x/1 HTTP/1.1\r\n"
7075 "Host: www.example.org\r\n"
7076 "Connection: keep-alive\r\n"
7077 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237078 };
7079
7080 // Sever accepts the authorization.
7081 MockRead data_reads2[] = {
7082 MockRead("HTTP/1.0 200 OK\r\n"),
7083 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067084 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237085 };
7086
[email protected]31a2bfe2010-02-09 08:03:397087 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7088 data_writes1, arraysize(data_writes1));
7089 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7090 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077091 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7092 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237093
[email protected]49639fa2011-12-20 23:22:417094 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237095
[email protected]49639fa2011-12-20 23:22:417096 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427097 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237098
7099 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427100 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237101
[email protected]0757e7702009-03-27 04:00:227102 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417103 TestCompletionCallback callback2;
7104 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:427105 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:227106 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427107 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:227108 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
7109
[email protected]1c773ea12009-04-28 19:58:427110 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527111 ASSERT_TRUE(response);
7112 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237113 EXPECT_EQ(100, response->headers->GetContentLength());
7114 }
7115
7116 // ------------------------------------------------------------------------
7117
7118 // Transaction 5: request a URL in MyRealm, but the server rejects the
7119 // cached identity. Should invalidate and re-prompt.
7120 {
[email protected]1c773ea12009-04-28 19:58:427121 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237122 request.method = "GET";
bncce36dca22015-04-21 22:11:237123 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237124 request.load_flags = 0;
7125
danakj1fd259a02016-04-16 03:17:097126 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507127 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277128
[email protected]f9ee6b52008-11-08 06:46:237129 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237130 MockWrite(
7131 "GET /p/q/t HTTP/1.1\r\n"
7132 "Host: www.example.org\r\n"
7133 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237134 };
7135
7136 MockRead data_reads1[] = {
7137 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7138 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7139 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067140 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237141 };
7142
7143 // Resend with authorization from cache for MyRealm.
7144 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237145 MockWrite(
7146 "GET /p/q/t HTTP/1.1\r\n"
7147 "Host: www.example.org\r\n"
7148 "Connection: keep-alive\r\n"
7149 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237150 };
7151
7152 // Sever rejects the authorization.
7153 MockRead data_reads2[] = {
7154 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7155 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7156 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067157 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237158 };
7159
7160 // At this point we should prompt for new credentials for MyRealm.
7161 // Restart with username=foo3, password=foo4.
7162 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237163 MockWrite(
7164 "GET /p/q/t HTTP/1.1\r\n"
7165 "Host: www.example.org\r\n"
7166 "Connection: keep-alive\r\n"
7167 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237168 };
7169
7170 // Sever accepts the authorization.
7171 MockRead data_reads3[] = {
7172 MockRead("HTTP/1.0 200 OK\r\n"),
7173 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067174 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237175 };
7176
[email protected]31a2bfe2010-02-09 08:03:397177 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7178 data_writes1, arraysize(data_writes1));
7179 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7180 data_writes2, arraysize(data_writes2));
7181 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7182 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077183 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7184 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7185 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237186
[email protected]49639fa2011-12-20 23:22:417187 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237188
[email protected]49639fa2011-12-20 23:22:417189 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427190 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237191
7192 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427193 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237194
[email protected]0757e7702009-03-27 04:00:227195 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417196 TestCompletionCallback callback2;
7197 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:427198 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:227199 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427200 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:227201 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
7202
[email protected]1c773ea12009-04-28 19:58:427203 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527204 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047205 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237206
[email protected]49639fa2011-12-20 23:22:417207 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237208
[email protected]49639fa2011-12-20 23:22:417209 rv = trans->RestartWithAuth(
7210 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:427211 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237212
[email protected]0757e7702009-03-27 04:00:227213 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427214 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237215
7216 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527217 ASSERT_TRUE(response);
7218 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237219 EXPECT_EQ(100, response->headers->GetContentLength());
7220 }
7221}
[email protected]89ceba9a2009-03-21 03:46:067222
[email protected]3c32c5f2010-05-18 15:18:127223// Tests that nonce count increments when multiple auth attempts
7224// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:027225TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447226 HttpAuthHandlerDigest::Factory* digest_factory =
7227 new HttpAuthHandlerDigest::Factory();
7228 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7229 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7230 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077231 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097232 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127233
7234 // Transaction 1: authenticate (foo, bar) on MyRealm1
7235 {
[email protected]3c32c5f2010-05-18 15:18:127236 HttpRequestInfo request;
7237 request.method = "GET";
bncce36dca22015-04-21 22:11:237238 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127239 request.load_flags = 0;
7240
danakj1fd259a02016-04-16 03:17:097241 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507242 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277243
[email protected]3c32c5f2010-05-18 15:18:127244 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237245 MockWrite(
7246 "GET /x/y/z HTTP/1.1\r\n"
7247 "Host: www.example.org\r\n"
7248 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127249 };
7250
7251 MockRead data_reads1[] = {
7252 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7253 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7254 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067255 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127256 };
7257
7258 // Resend with authorization (username=foo, password=bar)
7259 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237260 MockWrite(
7261 "GET /x/y/z HTTP/1.1\r\n"
7262 "Host: www.example.org\r\n"
7263 "Connection: keep-alive\r\n"
7264 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7265 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7266 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7267 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127268 };
7269
7270 // Sever accepts the authorization.
7271 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087272 MockRead("HTTP/1.0 200 OK\r\n"),
7273 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127274 };
7275
7276 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7277 data_writes1, arraysize(data_writes1));
7278 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7279 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077280 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7281 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127282
[email protected]49639fa2011-12-20 23:22:417283 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127284
[email protected]49639fa2011-12-20 23:22:417285 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:127286 EXPECT_EQ(ERR_IO_PENDING, rv);
7287
7288 rv = callback1.WaitForResult();
7289 EXPECT_EQ(OK, rv);
7290
7291 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527292 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047293 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127294
[email protected]49639fa2011-12-20 23:22:417295 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127296
[email protected]49639fa2011-12-20 23:22:417297 rv = trans->RestartWithAuth(
7298 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:127299 EXPECT_EQ(ERR_IO_PENDING, rv);
7300
7301 rv = callback2.WaitForResult();
7302 EXPECT_EQ(OK, rv);
7303
7304 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527305 ASSERT_TRUE(response);
7306 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127307 }
7308
7309 // ------------------------------------------------------------------------
7310
7311 // Transaction 2: Request another resource in digestive's protection space.
7312 // This will preemptively add an Authorization header which should have an
7313 // "nc" value of 2 (as compared to 1 in the first use.
7314 {
[email protected]3c32c5f2010-05-18 15:18:127315 HttpRequestInfo request;
7316 request.method = "GET";
7317 // Note that Transaction 1 was at /x/y/z, so this is in the same
7318 // protection space as digest.
bncce36dca22015-04-21 22:11:237319 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127320 request.load_flags = 0;
7321
danakj1fd259a02016-04-16 03:17:097322 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507323 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277324
[email protected]3c32c5f2010-05-18 15:18:127325 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237326 MockWrite(
7327 "GET /x/y/a/b HTTP/1.1\r\n"
7328 "Host: www.example.org\r\n"
7329 "Connection: keep-alive\r\n"
7330 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7331 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7332 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7333 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127334 };
7335
7336 // Sever accepts the authorization.
7337 MockRead data_reads1[] = {
7338 MockRead("HTTP/1.0 200 OK\r\n"),
7339 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067340 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127341 };
7342
7343 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7344 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077345 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127346
[email protected]49639fa2011-12-20 23:22:417347 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127348
[email protected]49639fa2011-12-20 23:22:417349 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:127350 EXPECT_EQ(ERR_IO_PENDING, rv);
7351
7352 rv = callback1.WaitForResult();
7353 EXPECT_EQ(OK, rv);
7354
7355 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527356 ASSERT_TRUE(response);
7357 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127358 }
7359}
7360
[email protected]89ceba9a2009-03-21 03:46:067361// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:027362TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067363 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097364 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7365 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:417366 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:067367
7368 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:067369 trans->read_buf_ = new IOBuffer(15);
7370 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:207371 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067372
7373 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:147374 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:577375 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087376 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577377 response->response_time = base::Time::Now();
7378 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067379
7380 { // Setup state for response_.vary_data
7381 HttpRequestInfo request;
7382 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7383 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277384 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437385 request.extra_headers.SetHeader("Foo", "1");
7386 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507387 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067388 }
7389
7390 // Cause the above state to be reset.
7391 trans->ResetStateForRestart();
7392
7393 // Verify that the state that needed to be reset, has been reset.
wezca1070932016-05-26 20:30:527394 EXPECT_FALSE(trans->read_buf_);
[email protected]89ceba9a2009-03-21 03:46:067395 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:207396 EXPECT_TRUE(trans->request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527397 EXPECT_FALSE(response->auth_challenge);
7398 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047399 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087400 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577401 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067402}
7403
[email protected]bacff652009-03-31 17:50:337404// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:027405TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337406 HttpRequestInfo request;
7407 request.method = "GET";
bncce36dca22015-04-21 22:11:237408 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337409 request.load_flags = 0;
7410
danakj1fd259a02016-04-16 03:17:097411 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7412 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417413 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277414
[email protected]bacff652009-03-31 17:50:337415 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237416 MockWrite(
7417 "GET / HTTP/1.1\r\n"
7418 "Host: www.example.org\r\n"
7419 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337420 };
7421
7422 MockRead data_reads[] = {
7423 MockRead("HTTP/1.0 200 OK\r\n"),
7424 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7425 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067426 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337427 };
7428
[email protected]5ecc992a42009-11-11 01:41:597429 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397430 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7431 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067432 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7433 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337434
[email protected]bb88e1d32013-05-03 23:11:077435 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7436 session_deps_.socket_factory->AddSocketDataProvider(&data);
7437 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7438 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337439
[email protected]49639fa2011-12-20 23:22:417440 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337441
[email protected]49639fa2011-12-20 23:22:417442 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337443 EXPECT_EQ(ERR_IO_PENDING, rv);
7444
7445 rv = callback.WaitForResult();
7446 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7447
[email protected]49639fa2011-12-20 23:22:417448 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337449 EXPECT_EQ(ERR_IO_PENDING, rv);
7450
7451 rv = callback.WaitForResult();
7452 EXPECT_EQ(OK, rv);
7453
7454 const HttpResponseInfo* response = trans->GetResponseInfo();
7455
wezca1070932016-05-26 20:30:527456 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337457 EXPECT_EQ(100, response->headers->GetContentLength());
7458}
7459
7460// Test HTTPS connections to a site with a bad certificate, going through a
7461// proxy
[email protected]23e482282013-06-14 16:08:027462TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037463 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337464
7465 HttpRequestInfo request;
7466 request.method = "GET";
bncce36dca22015-04-21 22:11:237467 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337468 request.load_flags = 0;
7469
7470 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177471 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7472 "Host: www.example.org:443\r\n"
7473 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337474 };
7475
7476 MockRead proxy_reads[] = {
7477 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067478 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337479 };
7480
7481 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177482 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7483 "Host: www.example.org:443\r\n"
7484 "Proxy-Connection: keep-alive\r\n\r\n"),
7485 MockWrite("GET / HTTP/1.1\r\n"
7486 "Host: www.example.org\r\n"
7487 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337488 };
7489
7490 MockRead data_reads[] = {
7491 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7492 MockRead("HTTP/1.0 200 OK\r\n"),
7493 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7494 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067495 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337496 };
7497
[email protected]31a2bfe2010-02-09 08:03:397498 StaticSocketDataProvider ssl_bad_certificate(
7499 proxy_reads, arraysize(proxy_reads),
7500 proxy_writes, arraysize(proxy_writes));
7501 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7502 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067503 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7504 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337505
[email protected]bb88e1d32013-05-03 23:11:077506 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7507 session_deps_.socket_factory->AddSocketDataProvider(&data);
7508 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7509 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337510
[email protected]49639fa2011-12-20 23:22:417511 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337512
7513 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077514 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337515
danakj1fd259a02016-04-16 03:17:097516 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7517 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417518 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:337519
[email protected]49639fa2011-12-20 23:22:417520 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337521 EXPECT_EQ(ERR_IO_PENDING, rv);
7522
7523 rv = callback.WaitForResult();
7524 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7525
[email protected]49639fa2011-12-20 23:22:417526 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337527 EXPECT_EQ(ERR_IO_PENDING, rv);
7528
7529 rv = callback.WaitForResult();
7530 EXPECT_EQ(OK, rv);
7531
7532 const HttpResponseInfo* response = trans->GetResponseInfo();
7533
wezca1070932016-05-26 20:30:527534 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337535 EXPECT_EQ(100, response->headers->GetContentLength());
7536 }
7537}
7538
[email protected]2df19bb2010-08-25 20:13:467539
7540// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:027541TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037542 session_deps_.proxy_service =
7543 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517544 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077545 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467546
7547 HttpRequestInfo request;
7548 request.method = "GET";
bncce36dca22015-04-21 22:11:237549 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467550 request.load_flags = 0;
7551
7552 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177553 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7554 "Host: www.example.org:443\r\n"
7555 "Proxy-Connection: keep-alive\r\n\r\n"),
7556 MockWrite("GET / HTTP/1.1\r\n"
7557 "Host: www.example.org\r\n"
7558 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467559 };
7560
7561 MockRead data_reads[] = {
7562 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7563 MockRead("HTTP/1.1 200 OK\r\n"),
7564 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7565 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067566 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467567 };
7568
7569 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7570 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067571 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7572 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467573
[email protected]bb88e1d32013-05-03 23:11:077574 session_deps_.socket_factory->AddSocketDataProvider(&data);
7575 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7576 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467577
[email protected]49639fa2011-12-20 23:22:417578 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467579
danakj1fd259a02016-04-16 03:17:097580 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7581 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417582 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467583
[email protected]49639fa2011-12-20 23:22:417584 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467585 EXPECT_EQ(ERR_IO_PENDING, rv);
7586
7587 rv = callback.WaitForResult();
7588 EXPECT_EQ(OK, rv);
7589 const HttpResponseInfo* response = trans->GetResponseInfo();
7590
wezca1070932016-05-26 20:30:527591 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467592
7593 EXPECT_TRUE(response->headers->IsKeepAlive());
7594 EXPECT_EQ(200, response->headers->response_code());
7595 EXPECT_EQ(100, response->headers->GetContentLength());
7596 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207597
7598 LoadTimingInfo load_timing_info;
7599 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7600 TestLoadTimingNotReusedWithPac(load_timing_info,
7601 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467602}
7603
[email protected]511f6f52010-12-17 03:58:297604// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027605TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037606 session_deps_.proxy_service =
7607 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517608 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077609 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297610
7611 HttpRequestInfo request;
7612 request.method = "GET";
bncce36dca22015-04-21 22:11:237613 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297614 request.load_flags = 0;
7615
7616 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177617 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7618 "Host: www.example.org:443\r\n"
7619 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297620 };
7621
7622 MockRead data_reads[] = {
7623 MockRead("HTTP/1.1 302 Redirect\r\n"),
7624 MockRead("Location: http://login.example.com/\r\n"),
7625 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067626 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297627 };
7628
7629 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7630 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067631 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297632
[email protected]bb88e1d32013-05-03 23:11:077633 session_deps_.socket_factory->AddSocketDataProvider(&data);
7634 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297635
[email protected]49639fa2011-12-20 23:22:417636 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297637
danakj1fd259a02016-04-16 03:17:097638 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7639 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417640 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297641
[email protected]49639fa2011-12-20 23:22:417642 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297643 EXPECT_EQ(ERR_IO_PENDING, rv);
7644
7645 rv = callback.WaitForResult();
7646 EXPECT_EQ(OK, rv);
7647 const HttpResponseInfo* response = trans->GetResponseInfo();
7648
wezca1070932016-05-26 20:30:527649 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297650
7651 EXPECT_EQ(302, response->headers->response_code());
7652 std::string url;
7653 EXPECT_TRUE(response->headers->IsRedirect(&url));
7654 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207655
7656 // In the case of redirects from proxies, HttpNetworkTransaction returns
7657 // timing for the proxy connection instead of the connection to the host,
7658 // and no send / receive times.
7659 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7660 LoadTimingInfo load_timing_info;
7661 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7662
7663 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:297664 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207665
7666 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7667 EXPECT_LE(load_timing_info.proxy_resolve_start,
7668 load_timing_info.proxy_resolve_end);
7669 EXPECT_LE(load_timing_info.proxy_resolve_end,
7670 load_timing_info.connect_timing.connect_start);
7671 ExpectConnectTimingHasTimes(
7672 load_timing_info.connect_timing,
7673 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7674
7675 EXPECT_TRUE(load_timing_info.send_start.is_null());
7676 EXPECT_TRUE(load_timing_info.send_end.is_null());
7677 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297678}
7679
7680// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027681TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037682 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297683
7684 HttpRequestInfo request;
7685 request.method = "GET";
bncce36dca22015-04-21 22:11:237686 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297687 request.load_flags = 0;
7688
danakj1fd259a02016-04-16 03:17:097689 std::unique_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237690 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097691 std::unique_ptr<SpdySerializedFrame> goaway(
[email protected]c10b20852013-05-15 21:29:207692 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297693 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137694 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
7695 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297696 };
7697
7698 static const char* const kExtraHeaders[] = {
7699 "location",
7700 "http://login.example.com/",
7701 };
danakj1fd259a02016-04-16 03:17:097702 std::unique_ptr<SpdySerializedFrame> resp(
7703 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
7704 arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297705 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137706 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297707 };
7708
rch8e6c6c42015-05-01 14:05:137709 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7710 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067711 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387712 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297713
[email protected]bb88e1d32013-05-03 23:11:077714 session_deps_.socket_factory->AddSocketDataProvider(&data);
7715 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297716
[email protected]49639fa2011-12-20 23:22:417717 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297718
danakj1fd259a02016-04-16 03:17:097719 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7720 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417721 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297722
[email protected]49639fa2011-12-20 23:22:417723 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297724 EXPECT_EQ(ERR_IO_PENDING, rv);
7725
7726 rv = callback.WaitForResult();
7727 EXPECT_EQ(OK, rv);
7728 const HttpResponseInfo* response = trans->GetResponseInfo();
7729
wezca1070932016-05-26 20:30:527730 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297731
7732 EXPECT_EQ(302, response->headers->response_code());
7733 std::string url;
7734 EXPECT_TRUE(response->headers->IsRedirect(&url));
7735 EXPECT_EQ("http://login.example.com/", url);
7736}
7737
[email protected]4eddbc732012-08-09 05:40:177738// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027739TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177740 ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037741 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297742
7743 HttpRequestInfo request;
7744 request.method = "GET";
bncce36dca22015-04-21 22:11:237745 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297746 request.load_flags = 0;
7747
7748 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177749 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7750 "Host: www.example.org:443\r\n"
7751 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297752 };
7753
7754 MockRead data_reads[] = {
7755 MockRead("HTTP/1.1 404 Not Found\r\n"),
7756 MockRead("Content-Length: 23\r\n\r\n"),
7757 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067758 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297759 };
7760
7761 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7762 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067763 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297764
[email protected]bb88e1d32013-05-03 23:11:077765 session_deps_.socket_factory->AddSocketDataProvider(&data);
7766 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297767
[email protected]49639fa2011-12-20 23:22:417768 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297769
danakj1fd259a02016-04-16 03:17:097770 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7771 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417772 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297773
[email protected]49639fa2011-12-20 23:22:417774 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297775 EXPECT_EQ(ERR_IO_PENDING, rv);
7776
7777 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177778 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297779
ttuttle960fcbf2016-04-19 13:26:327780 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297781}
7782
[email protected]4eddbc732012-08-09 05:40:177783// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027784TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177785 ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037786 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297787
7788 HttpRequestInfo request;
7789 request.method = "GET";
bncce36dca22015-04-21 22:11:237790 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297791 request.load_flags = 0;
7792
danakj1fd259a02016-04-16 03:17:097793 std::unique_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237794 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097795 std::unique_ptr<SpdySerializedFrame> rst(
[email protected]c10b20852013-05-15 21:29:207796 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297797 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137798 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:297799 };
7800
7801 static const char* const kExtraHeaders[] = {
7802 "location",
7803 "http://login.example.com/",
7804 };
danakj1fd259a02016-04-16 03:17:097805 std::unique_ptr<SpdySerializedFrame> resp(
7806 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
7807 arraysize(kExtraHeaders) / 2, 1));
7808 std::unique_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame(
bncb03b1092016-04-06 11:19:557809 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297810 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137811 CreateMockRead(*resp.get(), 1),
7812 CreateMockRead(*body.get(), 2),
7813 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297814 };
7815
rch8e6c6c42015-05-01 14:05:137816 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7817 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067818 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387819 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297820
[email protected]bb88e1d32013-05-03 23:11:077821 session_deps_.socket_factory->AddSocketDataProvider(&data);
7822 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297823
[email protected]49639fa2011-12-20 23:22:417824 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297825
danakj1fd259a02016-04-16 03:17:097826 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7827 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417828 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297829
[email protected]49639fa2011-12-20 23:22:417830 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297831 EXPECT_EQ(ERR_IO_PENDING, rv);
7832
7833 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177834 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297835
ttuttle960fcbf2016-04-19 13:26:327836 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297837}
7838
[email protected]0c5fb722012-02-28 11:50:357839// Test the request-challenge-retry sequence for basic auth, through
7840// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:027841TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:357842 HttpRequestInfo request;
7843 request.method = "GET";
bncce36dca22015-04-21 22:11:237844 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:357845 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:297846 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:357847
7848 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037849 session_deps_.proxy_service =
7850 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517851 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077852 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:097853 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:357854
7855 // Since we have proxy, should try to establish tunnel.
danakj1fd259a02016-04-16 03:17:097856 std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237857 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097858 std::unique_ptr<SpdySerializedFrame> rst(
[email protected]c10b20852013-05-15 21:29:207859 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
rdsmithebb50aa2015-11-12 03:44:387860 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:357861
7862 // After calling trans->RestartWithAuth(), this is the request we should
7863 // be issuing -- the final header line contains the credentials.
7864 const char* const kAuthCredentials[] = {
7865 "proxy-authorization", "Basic Zm9vOmJhcg==",
7866 };
danakj1fd259a02016-04-16 03:17:097867 std::unique_ptr<SpdySerializedFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:347868 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:237869 HostPortPair("www.example.org", 443)));
7870 // fetch https://www.example.org/ via HTTP
7871 const char get[] =
7872 "GET / HTTP/1.1\r\n"
7873 "Host: www.example.org\r\n"
7874 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:097875 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:027876 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:357877
7878 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137879 CreateMockWrite(*req, 0, ASYNC),
7880 CreateMockWrite(*rst, 2, ASYNC),
7881 CreateMockWrite(*connect2, 3),
7882 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:357883 };
7884
7885 // The proxy responds to the connect with a 407, using a persistent
7886 // connection.
thestig9d3bb0c2015-01-24 00:49:517887 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:357888 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:357889 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
7890 };
danakj1fd259a02016-04-16 03:17:097891 std::unique_ptr<SpdySerializedFrame> conn_auth_resp(
bncb03b1092016-04-06 11:19:557892 spdy_util_.ConstructSpdySynReplyError(kAuthStatus, kAuthChallenge,
7893 arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:357894
danakj1fd259a02016-04-16 03:17:097895 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:027896 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:357897 const char resp[] = "HTTP/1.1 200 OK\r\n"
7898 "Content-Length: 5\r\n\r\n";
7899
danakj1fd259a02016-04-16 03:17:097900 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:027901 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
danakj1fd259a02016-04-16 03:17:097902 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:027903 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:357904 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137905 CreateMockRead(*conn_auth_resp, 1, ASYNC),
7906 CreateMockRead(*conn_resp, 4, ASYNC),
7907 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
7908 CreateMockRead(*wrapped_body, 7, ASYNC),
7909 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:357910 };
7911
rch8e6c6c42015-05-01 14:05:137912 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7913 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077914 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:357915 // Negotiate SPDY to the proxy
7916 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387917 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077918 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:357919 // Vanilla SSL to the server
7920 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077921 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:357922
7923 TestCompletionCallback callback1;
7924
danakj1fd259a02016-04-16 03:17:097925 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507926 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:357927
7928 int rv = trans->Start(&request, callback1.callback(), log.bound());
7929 EXPECT_EQ(ERR_IO_PENDING, rv);
7930
7931 rv = callback1.WaitForResult();
7932 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:467933 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:357934 log.GetEntries(&entries);
7935 size_t pos = ExpectLogContainsSomewhere(
7936 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
7937 NetLog::PHASE_NONE);
7938 ExpectLogContainsSomewhere(
7939 entries, pos,
7940 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
7941 NetLog::PHASE_NONE);
7942
7943 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527944 ASSERT_TRUE(response);
7945 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:357946 EXPECT_EQ(407, response->headers->response_code());
7947 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:527948 EXPECT_TRUE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:357949 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
7950
7951 TestCompletionCallback callback2;
7952
7953 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
7954 callback2.callback());
7955 EXPECT_EQ(ERR_IO_PENDING, rv);
7956
7957 rv = callback2.WaitForResult();
7958 EXPECT_EQ(OK, rv);
7959
7960 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527961 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:357962
7963 EXPECT_TRUE(response->headers->IsKeepAlive());
7964 EXPECT_EQ(200, response->headers->response_code());
7965 EXPECT_EQ(5, response->headers->GetContentLength());
7966 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7967
7968 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:527969 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:357970
[email protected]029c83b62013-01-24 05:28:207971 LoadTimingInfo load_timing_info;
7972 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7973 TestLoadTimingNotReusedWithPac(load_timing_info,
7974 CONNECT_TIMING_HAS_SSL_TIMES);
7975
[email protected]0c5fb722012-02-28 11:50:357976 trans.reset();
7977 session->CloseAllConnections();
7978}
7979
[email protected]7c6f7ba2012-04-03 04:09:297980// Test that an explicitly trusted SPDY proxy can push a resource from an
7981// origin that is different from that of its associated resource.
tbansal28e68f82016-02-04 02:56:157982TEST_P(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
7983 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:097984 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:157985 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
7986 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:297987 HttpRequestInfo request;
7988 HttpRequestInfo push_request;
7989
[email protected]7c6f7ba2012-04-03 04:09:297990 request.method = "GET";
bncce36dca22015-04-21 22:11:237991 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:297992 push_request.method = "GET";
7993 push_request.url = GURL("http://www.another-origin.com/foo.dat");
7994
tbansal28e68f82016-02-04 02:56:157995 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:037996 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:157997 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:517998 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077999 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508000
tbansal28e68f82016-02-04 02:56:158001 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:508002
danakj1fd259a02016-04-16 03:17:098003 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298004
danakj1fd259a02016-04-16 03:17:098005 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:498006 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:298007
8008 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:138009 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298010 };
8011
danakj1fd259a02016-04-16 03:17:098012 std::unique_ptr<SpdySerializedFrame> stream1_reply(
bncb03b1092016-04-06 11:19:558013 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298014
danakj1fd259a02016-04-16 03:17:098015 std::unique_ptr<SpdySerializedFrame> stream1_body(
bncb03b1092016-04-06 11:19:558016 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298017
danakj1fd259a02016-04-16 03:17:098018 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558019 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438020 const char kPushedData[] = "pushed";
danakj1fd259a02016-04-16 03:17:098021 std::unique_ptr<SpdySerializedFrame> stream2_body(
bncb03b1092016-04-06 11:19:558022 spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
8023 true));
[email protected]7c6f7ba2012-04-03 04:09:298024
8025 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:138026 CreateMockRead(*stream1_reply, 1, ASYNC),
8027 CreateMockRead(*stream2_syn, 2, ASYNC),
8028 CreateMockRead(*stream1_body, 3, ASYNC),
8029 CreateMockRead(*stream2_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598030 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298031 };
8032
rch8e6c6c42015-05-01 14:05:138033 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8034 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078035 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298036 // Negotiate SPDY to the proxy
8037 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:388038 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:078039 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298040
danakj1fd259a02016-04-16 03:17:098041 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508042 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:298043 TestCompletionCallback callback;
8044 int rv = trans->Start(&request, callback.callback(), log.bound());
8045 EXPECT_EQ(ERR_IO_PENDING, rv);
8046
8047 rv = callback.WaitForResult();
8048 EXPECT_EQ(OK, rv);
8049 const HttpResponseInfo* response = trans->GetResponseInfo();
8050
danakj1fd259a02016-04-16 03:17:098051 std::unique_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:508052 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8053 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:298054 EXPECT_EQ(ERR_IO_PENDING, rv);
8055
8056 rv = callback.WaitForResult();
8057 EXPECT_EQ(OK, rv);
8058 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8059
wezca1070932016-05-26 20:30:528060 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298061 EXPECT_TRUE(response->headers->IsKeepAlive());
8062
8063 EXPECT_EQ(200, response->headers->response_code());
8064 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8065
8066 std::string response_data;
8067 rv = ReadTransaction(trans.get(), &response_data);
8068 EXPECT_EQ(OK, rv);
8069 EXPECT_EQ("hello!", response_data);
8070
[email protected]029c83b62013-01-24 05:28:208071 LoadTimingInfo load_timing_info;
8072 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8073 TestLoadTimingNotReusedWithPac(load_timing_info,
8074 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8075
[email protected]7c6f7ba2012-04-03 04:09:298076 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528077 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298078 EXPECT_EQ(200, push_response->headers->response_code());
8079
8080 rv = ReadTransaction(push_trans.get(), &response_data);
8081 EXPECT_EQ(OK, rv);
8082 EXPECT_EQ("pushed", response_data);
8083
[email protected]029c83b62013-01-24 05:28:208084 LoadTimingInfo push_load_timing_info;
8085 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8086 TestLoadTimingReusedWithPac(push_load_timing_info);
8087 // The transactions should share a socket ID, despite being for different
8088 // origins.
8089 EXPECT_EQ(load_timing_info.socket_log_id,
8090 push_load_timing_info.socket_log_id);
8091
[email protected]7c6f7ba2012-04-03 04:09:298092 trans.reset();
8093 push_trans.reset();
8094 session->CloseAllConnections();
8095}
8096
[email protected]8c843192012-04-05 07:15:008097// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:028098TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158099 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098100 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158101 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8102 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008103 HttpRequestInfo request;
8104
8105 request.method = "GET";
bncce36dca22015-04-21 22:11:238106 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008107
tbansal28e68f82016-02-04 02:56:158108 session_deps_.proxy_service =
8109 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518110 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078111 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508112
8113 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158114 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:508115
danakj1fd259a02016-04-16 03:17:098116 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008117
danakj1fd259a02016-04-16 03:17:098118 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:498119 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:008120
danakj1fd259a02016-04-16 03:17:098121 std::unique_ptr<SpdySerializedFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:208122 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008123
8124 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:138125 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:008126 };
8127
danakj1fd259a02016-04-16 03:17:098128 std::unique_ptr<SpdySerializedFrame> stream1_reply(
bncb03b1092016-04-06 11:19:558129 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008130
danakj1fd259a02016-04-16 03:17:098131 std::unique_ptr<SpdySerializedFrame> stream1_body(
bncb03b1092016-04-06 11:19:558132 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:008133
danakj1fd259a02016-04-16 03:17:098134 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558135 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008136
8137 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:138138 CreateMockRead(*stream1_reply, 1, ASYNC),
8139 CreateMockRead(*stream2_syn, 2, ASYNC),
8140 CreateMockRead(*stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598141 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008142 };
8143
rch8e6c6c42015-05-01 14:05:138144 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8145 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078146 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008147 // Negotiate SPDY to the proxy
8148 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:388149 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:078150 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008151
danakj1fd259a02016-04-16 03:17:098152 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508153 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:008154 TestCompletionCallback callback;
8155 int rv = trans->Start(&request, callback.callback(), log.bound());
8156 EXPECT_EQ(ERR_IO_PENDING, rv);
8157
8158 rv = callback.WaitForResult();
8159 EXPECT_EQ(OK, rv);
8160 const HttpResponseInfo* response = trans->GetResponseInfo();
8161
wezca1070932016-05-26 20:30:528162 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008163 EXPECT_TRUE(response->headers->IsKeepAlive());
8164
8165 EXPECT_EQ(200, response->headers->response_code());
8166 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8167
8168 std::string response_data;
8169 rv = ReadTransaction(trans.get(), &response_data);
8170 EXPECT_EQ(OK, rv);
8171 EXPECT_EQ("hello!", response_data);
8172
8173 trans.reset();
8174 session->CloseAllConnections();
8175}
8176
tbansal8ef1d3e2016-02-03 04:05:428177// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8178// resources.
8179TEST_P(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158180 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098181 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158182 proxy_delegate->set_trusted_spdy_proxy(
8183 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8184
tbansal8ef1d3e2016-02-03 04:05:428185 HttpRequestInfo request;
8186
8187 request.method = "GET";
8188 request.url = GURL("http://www.example.org/");
8189
8190 // Configure against https proxy server "myproxy:70".
8191 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8192 BoundTestNetLog log;
8193 session_deps_.net_log = log.bound().net_log();
8194
8195 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158196 session_deps_.proxy_delegate.reset(proxy_delegate.release());
tbansal8ef1d3e2016-02-03 04:05:428197
danakj1fd259a02016-04-16 03:17:098198 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428199
danakj1fd259a02016-04-16 03:17:098200 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:498201 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
tbansal8ef1d3e2016-02-03 04:05:428202
8203 MockWrite spdy_writes[] = {
8204 CreateMockWrite(*stream1_syn, 0, ASYNC),
8205 };
8206
danakj1fd259a02016-04-16 03:17:098207 std::unique_ptr<SpdySerializedFrame> stream1_reply(
tbansal8ef1d3e2016-02-03 04:05:428208 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
8209
danakj1fd259a02016-04-16 03:17:098210 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498211 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8212
danakj1fd259a02016-04-16 03:17:098213 std::unique_ptr<SpdySerializedFrame> stream1_body(
tbansal8ef1d3e2016-02-03 04:05:428214 spdy_util_.ConstructSpdyBodyFrame(1, true));
8215
danakj1fd259a02016-04-16 03:17:098216 std::unique_ptr<SpdySerializedFrame> stream2_reply(
tbansal8ef1d3e2016-02-03 04:05:428217 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
8218
danakj1fd259a02016-04-16 03:17:098219 std::unique_ptr<SpdySerializedFrame> stream2_body(
tbansal8ef1d3e2016-02-03 04:05:428220 spdy_util_.ConstructSpdyBodyFrame(1, true));
8221
8222 MockRead spdy_reads[] = {
8223 CreateMockRead(*stream1_reply, 1, ASYNC),
8224 CreateMockRead(*stream2_syn, 2, ASYNC),
8225 CreateMockRead(*stream1_body, 3, ASYNC),
8226 CreateMockRead(*stream2_body, 4, ASYNC),
8227 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
8228 };
8229
8230 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8231 arraysize(spdy_writes));
8232 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8233 // Negotiate SPDY to the proxy
8234 SSLSocketDataProvider proxy(ASYNC, OK);
8235 proxy.SetNextProto(GetProtocol());
8236 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8237
danakj1fd259a02016-04-16 03:17:098238 std::unique_ptr<HttpTransaction> trans(
tbansal8ef1d3e2016-02-03 04:05:428239 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8240 TestCompletionCallback callback;
8241 int rv = trans->Start(&request, callback.callback(), log.bound());
8242 EXPECT_EQ(ERR_IO_PENDING, rv);
8243
8244 rv = callback.WaitForResult();
8245 EXPECT_EQ(OK, rv);
8246 const HttpResponseInfo* response = trans->GetResponseInfo();
8247
wezca1070932016-05-26 20:30:528248 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428249 EXPECT_TRUE(response->headers->IsKeepAlive());
8250
8251 EXPECT_EQ(200, response->headers->response_code());
8252 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8253
8254 std::string response_data;
8255 rv = ReadTransaction(trans.get(), &response_data);
8256 EXPECT_EQ(OK, rv);
8257 EXPECT_EQ("hello!", response_data);
8258
8259 trans.reset();
8260 session->CloseAllConnections();
8261}
8262
[email protected]2df19bb2010-08-25 20:13:468263// Test HTTPS connections to a site with a bad certificate, going through an
8264// HTTPS proxy
[email protected]23e482282013-06-14 16:08:028265TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038266 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468267
8268 HttpRequestInfo request;
8269 request.method = "GET";
bncce36dca22015-04-21 22:11:238270 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468271 request.load_flags = 0;
8272
8273 // Attempt to fetch the URL from a server with a bad cert
8274 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178275 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8276 "Host: www.example.org:443\r\n"
8277 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468278 };
8279
8280 MockRead bad_cert_reads[] = {
8281 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068282 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468283 };
8284
8285 // Attempt to fetch the URL with a good cert
8286 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178287 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8288 "Host: www.example.org:443\r\n"
8289 "Proxy-Connection: keep-alive\r\n\r\n"),
8290 MockWrite("GET / HTTP/1.1\r\n"
8291 "Host: www.example.org\r\n"
8292 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468293 };
8294
8295 MockRead good_cert_reads[] = {
8296 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8297 MockRead("HTTP/1.0 200 OK\r\n"),
8298 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8299 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068300 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468301 };
8302
8303 StaticSocketDataProvider ssl_bad_certificate(
8304 bad_cert_reads, arraysize(bad_cert_reads),
8305 bad_cert_writes, arraysize(bad_cert_writes));
8306 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8307 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068308 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8309 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468310
8311 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078312 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8313 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8314 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468315
8316 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078317 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8318 session_deps_.socket_factory->AddSocketDataProvider(&data);
8319 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468320
[email protected]49639fa2011-12-20 23:22:418321 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468322
danakj1fd259a02016-04-16 03:17:098323 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8324 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418325 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:468326
[email protected]49639fa2011-12-20 23:22:418327 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:468328 EXPECT_EQ(ERR_IO_PENDING, rv);
8329
8330 rv = callback.WaitForResult();
8331 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
8332
[email protected]49639fa2011-12-20 23:22:418333 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:468334 EXPECT_EQ(ERR_IO_PENDING, rv);
8335
8336 rv = callback.WaitForResult();
8337 EXPECT_EQ(OK, rv);
8338
8339 const HttpResponseInfo* response = trans->GetResponseInfo();
8340
wezca1070932016-05-26 20:30:528341 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468342 EXPECT_EQ(100, response->headers->GetContentLength());
8343}
8344
[email protected]23e482282013-06-14 16:08:028345TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428346 HttpRequestInfo request;
8347 request.method = "GET";
bncce36dca22015-04-21 22:11:238348 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438349 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8350 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428351
danakj1fd259a02016-04-16 03:17:098352 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8353 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418354 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278355
[email protected]1c773ea12009-04-28 19:58:428356 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238357 MockWrite(
8358 "GET / HTTP/1.1\r\n"
8359 "Host: www.example.org\r\n"
8360 "Connection: keep-alive\r\n"
8361 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428362 };
8363
8364 // Lastly, the server responds with the actual content.
8365 MockRead data_reads[] = {
8366 MockRead("HTTP/1.0 200 OK\r\n"),
8367 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8368 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068369 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428370 };
8371
[email protected]31a2bfe2010-02-09 08:03:398372 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8373 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078374 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428375
[email protected]49639fa2011-12-20 23:22:418376 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428377
[email protected]49639fa2011-12-20 23:22:418378 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428379 EXPECT_EQ(ERR_IO_PENDING, rv);
8380
8381 rv = callback.WaitForResult();
8382 EXPECT_EQ(OK, rv);
8383}
8384
[email protected]23e482282013-06-14 16:08:028385TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298386 HttpRequestInfo request;
8387 request.method = "GET";
bncce36dca22015-04-21 22:11:238388 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298389 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8390 "Chromium Ultra Awesome X Edition");
8391
rdsmith82957ad2015-09-16 19:42:038392 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8394 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418395 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278396
[email protected]da81f132010-08-18 23:39:298397 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178398 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8399 "Host: www.example.org:443\r\n"
8400 "Proxy-Connection: keep-alive\r\n"
8401 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298402 };
8403 MockRead data_reads[] = {
8404 // Return an error, so the transaction stops here (this test isn't
8405 // interested in the rest).
8406 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8407 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8408 MockRead("Proxy-Connection: close\r\n\r\n"),
8409 };
8410
8411 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8412 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078413 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298414
[email protected]49639fa2011-12-20 23:22:418415 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298416
[email protected]49639fa2011-12-20 23:22:418417 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:298418 EXPECT_EQ(ERR_IO_PENDING, rv);
8419
8420 rv = callback.WaitForResult();
8421 EXPECT_EQ(OK, rv);
8422}
8423
[email protected]23e482282013-06-14 16:08:028424TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428425 HttpRequestInfo request;
8426 request.method = "GET";
bncce36dca22015-04-21 22:11:238427 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428428 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:168429 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8430 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428431
danakj1fd259a02016-04-16 03:17:098432 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8433 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418434 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278435
[email protected]1c773ea12009-04-28 19:58:428436 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238437 MockWrite(
8438 "GET / HTTP/1.1\r\n"
8439 "Host: www.example.org\r\n"
8440 "Connection: keep-alive\r\n"
8441 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428442 };
8443
8444 // Lastly, the server responds with the actual content.
8445 MockRead data_reads[] = {
8446 MockRead("HTTP/1.0 200 OK\r\n"),
8447 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8448 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068449 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428450 };
8451
[email protected]31a2bfe2010-02-09 08:03:398452 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8453 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078454 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428455
[email protected]49639fa2011-12-20 23:22:418456 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428457
[email protected]49639fa2011-12-20 23:22:418458 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428459 EXPECT_EQ(ERR_IO_PENDING, rv);
8460
8461 rv = callback.WaitForResult();
8462 EXPECT_EQ(OK, rv);
8463}
8464
[email protected]23e482282013-06-14 16:08:028465TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428466 HttpRequestInfo request;
8467 request.method = "POST";
bncce36dca22015-04-21 22:11:238468 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428469
danakj1fd259a02016-04-16 03:17:098470 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8471 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418472 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278473
[email protected]1c773ea12009-04-28 19:58:428474 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238475 MockWrite(
8476 "POST / HTTP/1.1\r\n"
8477 "Host: www.example.org\r\n"
8478 "Connection: keep-alive\r\n"
8479 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428480 };
8481
8482 // Lastly, the server responds with the actual content.
8483 MockRead data_reads[] = {
8484 MockRead("HTTP/1.0 200 OK\r\n"),
8485 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8486 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068487 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428488 };
8489
[email protected]31a2bfe2010-02-09 08:03:398490 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8491 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078492 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428493
[email protected]49639fa2011-12-20 23:22:418494 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428495
[email protected]49639fa2011-12-20 23:22:418496 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428497 EXPECT_EQ(ERR_IO_PENDING, rv);
8498
8499 rv = callback.WaitForResult();
8500 EXPECT_EQ(OK, rv);
8501}
8502
[email protected]23e482282013-06-14 16:08:028503TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428504 HttpRequestInfo request;
8505 request.method = "PUT";
bncce36dca22015-04-21 22:11:238506 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428507
danakj1fd259a02016-04-16 03:17:098508 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8509 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418510 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278511
[email protected]1c773ea12009-04-28 19:58:428512 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238513 MockWrite(
8514 "PUT / HTTP/1.1\r\n"
8515 "Host: www.example.org\r\n"
8516 "Connection: keep-alive\r\n"
8517 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428518 };
8519
8520 // Lastly, the server responds with the actual content.
8521 MockRead data_reads[] = {
8522 MockRead("HTTP/1.0 200 OK\r\n"),
8523 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8524 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068525 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428526 };
8527
[email protected]31a2bfe2010-02-09 08:03:398528 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8529 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078530 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428531
[email protected]49639fa2011-12-20 23:22:418532 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428533
[email protected]49639fa2011-12-20 23:22:418534 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428535 EXPECT_EQ(ERR_IO_PENDING, rv);
8536
8537 rv = callback.WaitForResult();
8538 EXPECT_EQ(OK, rv);
8539}
8540
[email protected]23e482282013-06-14 16:08:028541TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428542 HttpRequestInfo request;
8543 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238544 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428545
danakj1fd259a02016-04-16 03:17:098546 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8547 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418548 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278549
[email protected]1c773ea12009-04-28 19:58:428550 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138551 MockWrite("HEAD / HTTP/1.1\r\n"
8552 "Host: www.example.org\r\n"
8553 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428554 };
8555
8556 // Lastly, the server responds with the actual content.
8557 MockRead data_reads[] = {
8558 MockRead("HTTP/1.0 200 OK\r\n"),
8559 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8560 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068561 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428562 };
8563
[email protected]31a2bfe2010-02-09 08:03:398564 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8565 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078566 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428567
[email protected]49639fa2011-12-20 23:22:418568 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428569
[email protected]49639fa2011-12-20 23:22:418570 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428571 EXPECT_EQ(ERR_IO_PENDING, rv);
8572
8573 rv = callback.WaitForResult();
8574 EXPECT_EQ(OK, rv);
8575}
8576
[email protected]23e482282013-06-14 16:08:028577TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428578 HttpRequestInfo request;
8579 request.method = "GET";
bncce36dca22015-04-21 22:11:238580 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428581 request.load_flags = LOAD_BYPASS_CACHE;
8582
danakj1fd259a02016-04-16 03:17:098583 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8584 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418585 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278586
[email protected]1c773ea12009-04-28 19:58:428587 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238588 MockWrite(
8589 "GET / HTTP/1.1\r\n"
8590 "Host: www.example.org\r\n"
8591 "Connection: keep-alive\r\n"
8592 "Pragma: no-cache\r\n"
8593 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428594 };
8595
8596 // Lastly, the server responds with the actual content.
8597 MockRead data_reads[] = {
8598 MockRead("HTTP/1.0 200 OK\r\n"),
8599 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8600 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068601 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428602 };
8603
[email protected]31a2bfe2010-02-09 08:03:398604 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8605 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078606 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428607
[email protected]49639fa2011-12-20 23:22:418608 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428609
[email protected]49639fa2011-12-20 23:22:418610 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428611 EXPECT_EQ(ERR_IO_PENDING, rv);
8612
8613 rv = callback.WaitForResult();
8614 EXPECT_EQ(OK, rv);
8615}
8616
[email protected]23e482282013-06-14 16:08:028617TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:428618 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428619 HttpRequestInfo request;
8620 request.method = "GET";
bncce36dca22015-04-21 22:11:238621 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428622 request.load_flags = LOAD_VALIDATE_CACHE;
8623
danakj1fd259a02016-04-16 03:17:098624 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8625 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418626 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278627
[email protected]1c773ea12009-04-28 19:58:428628 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238629 MockWrite(
8630 "GET / HTTP/1.1\r\n"
8631 "Host: www.example.org\r\n"
8632 "Connection: keep-alive\r\n"
8633 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428634 };
8635
8636 // Lastly, the server responds with the actual content.
8637 MockRead data_reads[] = {
8638 MockRead("HTTP/1.0 200 OK\r\n"),
8639 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8640 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068641 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428642 };
8643
[email protected]31a2bfe2010-02-09 08:03:398644 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8645 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078646 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428647
[email protected]49639fa2011-12-20 23:22:418648 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428649
[email protected]49639fa2011-12-20 23:22:418650 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428651 EXPECT_EQ(ERR_IO_PENDING, rv);
8652
8653 rv = callback.WaitForResult();
8654 EXPECT_EQ(OK, rv);
8655}
8656
[email protected]23e482282013-06-14 16:08:028657TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428658 HttpRequestInfo request;
8659 request.method = "GET";
bncce36dca22015-04-21 22:11:238660 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438661 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428662
danakj1fd259a02016-04-16 03:17:098663 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8664 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418665 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278666
[email protected]1c773ea12009-04-28 19:58:428667 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238668 MockWrite(
8669 "GET / HTTP/1.1\r\n"
8670 "Host: www.example.org\r\n"
8671 "Connection: keep-alive\r\n"
8672 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428673 };
8674
8675 // Lastly, the server responds with the actual content.
8676 MockRead data_reads[] = {
8677 MockRead("HTTP/1.0 200 OK\r\n"),
8678 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8679 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068680 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428681 };
8682
[email protected]31a2bfe2010-02-09 08:03:398683 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8684 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078685 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428686
[email protected]49639fa2011-12-20 23:22:418687 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428688
[email protected]49639fa2011-12-20 23:22:418689 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428690 EXPECT_EQ(ERR_IO_PENDING, rv);
8691
8692 rv = callback.WaitForResult();
8693 EXPECT_EQ(OK, rv);
8694}
8695
[email protected]23e482282013-06-14 16:08:028696TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478697 HttpRequestInfo request;
8698 request.method = "GET";
bncce36dca22015-04-21 22:11:238699 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438700 request.extra_headers.SetHeader("referer", "www.foo.com");
8701 request.extra_headers.SetHeader("hEllo", "Kitty");
8702 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478703
danakj1fd259a02016-04-16 03:17:098704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8705 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418706 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278707
[email protected]270c6412010-03-29 22:02:478708 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238709 MockWrite(
8710 "GET / HTTP/1.1\r\n"
8711 "Host: www.example.org\r\n"
8712 "Connection: keep-alive\r\n"
8713 "referer: www.foo.com\r\n"
8714 "hEllo: Kitty\r\n"
8715 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478716 };
8717
8718 // Lastly, the server responds with the actual content.
8719 MockRead data_reads[] = {
8720 MockRead("HTTP/1.0 200 OK\r\n"),
8721 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8722 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068723 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478724 };
8725
8726 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8727 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078728 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478729
[email protected]49639fa2011-12-20 23:22:418730 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478731
[email protected]49639fa2011-12-20 23:22:418732 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:478733 EXPECT_EQ(ERR_IO_PENDING, rv);
8734
8735 rv = callback.WaitForResult();
8736 EXPECT_EQ(OK, rv);
8737}
8738
[email protected]23e482282013-06-14 16:08:028739TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278740 HttpRequestInfo request;
8741 request.method = "GET";
bncce36dca22015-04-21 22:11:238742 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278743 request.load_flags = 0;
8744
rdsmith82957ad2015-09-16 19:42:038745 session_deps_.proxy_service =
8746 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518747 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078748 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028749
danakj1fd259a02016-04-16 03:17:098750 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8751 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418752 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028753
[email protected]3cd17242009-06-23 02:59:028754 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8755 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8756
8757 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238758 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8759 MockWrite(
8760 "GET / HTTP/1.1\r\n"
8761 "Host: www.example.org\r\n"
8762 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028763
8764 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068765 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028766 MockRead("HTTP/1.0 200 OK\r\n"),
8767 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8768 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068769 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028770 };
8771
[email protected]31a2bfe2010-02-09 08:03:398772 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8773 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078774 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028775
[email protected]49639fa2011-12-20 23:22:418776 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028777
[email protected]49639fa2011-12-20 23:22:418778 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028779 EXPECT_EQ(ERR_IO_PENDING, rv);
8780
8781 rv = callback.WaitForResult();
8782 EXPECT_EQ(OK, rv);
8783
8784 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528785 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028786
[email protected]029c83b62013-01-24 05:28:208787 LoadTimingInfo load_timing_info;
8788 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8789 TestLoadTimingNotReusedWithPac(load_timing_info,
8790 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8791
[email protected]3cd17242009-06-23 02:59:028792 std::string response_text;
8793 rv = ReadTransaction(trans.get(), &response_text);
8794 EXPECT_EQ(OK, rv);
8795 EXPECT_EQ("Payload", response_text);
8796}
8797
[email protected]23e482282013-06-14 16:08:028798TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278799 HttpRequestInfo request;
8800 request.method = "GET";
bncce36dca22015-04-21 22:11:238801 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278802 request.load_flags = 0;
8803
rdsmith82957ad2015-09-16 19:42:038804 session_deps_.proxy_service =
8805 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518806 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078807 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028808
danakj1fd259a02016-04-16 03:17:098809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8810 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418811 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028812
[email protected]3cd17242009-06-23 02:59:028813 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8814 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8815
8816 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238817 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8818 arraysize(write_buffer)),
8819 MockWrite(
8820 "GET / HTTP/1.1\r\n"
8821 "Host: www.example.org\r\n"
8822 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028823
8824 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018825 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8826 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358827 MockRead("HTTP/1.0 200 OK\r\n"),
8828 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8829 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068830 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358831 };
8832
[email protected]31a2bfe2010-02-09 08:03:398833 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8834 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078835 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358836
[email protected]8ddf8322012-02-23 18:08:068837 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078838 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358839
[email protected]49639fa2011-12-20 23:22:418840 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358841
[email protected]49639fa2011-12-20 23:22:418842 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358843 EXPECT_EQ(ERR_IO_PENDING, rv);
8844
8845 rv = callback.WaitForResult();
8846 EXPECT_EQ(OK, rv);
8847
[email protected]029c83b62013-01-24 05:28:208848 LoadTimingInfo load_timing_info;
8849 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8850 TestLoadTimingNotReusedWithPac(load_timing_info,
8851 CONNECT_TIMING_HAS_SSL_TIMES);
8852
[email protected]e0c27be2009-07-15 13:09:358853 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528854 ASSERT_TRUE(response);
[email protected]e0c27be2009-07-15 13:09:358855
8856 std::string response_text;
8857 rv = ReadTransaction(trans.get(), &response_text);
8858 EXPECT_EQ(OK, rv);
8859 EXPECT_EQ("Payload", response_text);
8860}
8861
[email protected]23e482282013-06-14 16:08:028862TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:208863 HttpRequestInfo request;
8864 request.method = "GET";
bncce36dca22015-04-21 22:11:238865 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:208866 request.load_flags = 0;
8867
rdsmith82957ad2015-09-16 19:42:038868 session_deps_.proxy_service =
8869 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518870 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078871 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:208872
danakj1fd259a02016-04-16 03:17:098873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8874 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:208876
8877 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8878 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8879
8880 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238881 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8882 MockWrite(
8883 "GET / HTTP/1.1\r\n"
8884 "Host: www.example.org\r\n"
8885 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:208886
8887 MockRead data_reads[] = {
8888 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
8889 MockRead("HTTP/1.0 200 OK\r\n"),
8890 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8891 MockRead("Payload"),
8892 MockRead(SYNCHRONOUS, OK)
8893 };
8894
8895 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8896 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078897 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:208898
8899 TestCompletionCallback callback;
8900
8901 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8902 EXPECT_EQ(ERR_IO_PENDING, rv);
8903
8904 rv = callback.WaitForResult();
8905 EXPECT_EQ(OK, rv);
8906
8907 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528908 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:208909
8910 LoadTimingInfo load_timing_info;
8911 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8912 TestLoadTimingNotReused(load_timing_info,
8913 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8914
8915 std::string response_text;
8916 rv = ReadTransaction(trans.get(), &response_text);
8917 EXPECT_EQ(OK, rv);
8918 EXPECT_EQ("Payload", response_text);
8919}
8920
[email protected]23e482282013-06-14 16:08:028921TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278922 HttpRequestInfo request;
8923 request.method = "GET";
bncce36dca22015-04-21 22:11:238924 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278925 request.load_flags = 0;
8926
rdsmith82957ad2015-09-16 19:42:038927 session_deps_.proxy_service =
8928 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518929 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078930 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358931
danakj1fd259a02016-04-16 03:17:098932 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8933 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418934 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358935
[email protected]e0c27be2009-07-15 13:09:358936 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8937 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378938 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238939 0x05, // Version
8940 0x01, // Command (CONNECT)
8941 0x00, // Reserved.
8942 0x03, // Address type (DOMAINNAME).
8943 0x0F, // Length of domain (15)
8944 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8945 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:378946 };
[email protected]e0c27be2009-07-15 13:09:358947 const char kSOCKS5OkResponse[] =
8948 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
8949
8950 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238951 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8952 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
8953 MockWrite(
8954 "GET / HTTP/1.1\r\n"
8955 "Host: www.example.org\r\n"
8956 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358957
8958 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018959 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8960 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:358961 MockRead("HTTP/1.0 200 OK\r\n"),
8962 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8963 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068964 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358965 };
8966
[email protected]31a2bfe2010-02-09 08:03:398967 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8968 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078969 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358970
[email protected]49639fa2011-12-20 23:22:418971 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358972
[email protected]49639fa2011-12-20 23:22:418973 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358974 EXPECT_EQ(ERR_IO_PENDING, rv);
8975
8976 rv = callback.WaitForResult();
8977 EXPECT_EQ(OK, rv);
8978
8979 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528980 ASSERT_TRUE(response);
[email protected]e0c27be2009-07-15 13:09:358981
[email protected]029c83b62013-01-24 05:28:208982 LoadTimingInfo load_timing_info;
8983 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8984 TestLoadTimingNotReusedWithPac(load_timing_info,
8985 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8986
[email protected]e0c27be2009-07-15 13:09:358987 std::string response_text;
8988 rv = ReadTransaction(trans.get(), &response_text);
8989 EXPECT_EQ(OK, rv);
8990 EXPECT_EQ("Payload", response_text);
8991}
8992
[email protected]23e482282013-06-14 16:08:028993TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278994 HttpRequestInfo request;
8995 request.method = "GET";
bncce36dca22015-04-21 22:11:238996 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278997 request.load_flags = 0;
8998
rdsmith82957ad2015-09-16 19:42:038999 session_deps_.proxy_service =
9000 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519001 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079002 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359003
danakj1fd259a02016-04-16 03:17:099004 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9005 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419006 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:359007
[email protected]e0c27be2009-07-15 13:09:359008 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9009 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379010 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239011 0x05, // Version
9012 0x01, // Command (CONNECT)
9013 0x00, // Reserved.
9014 0x03, // Address type (DOMAINNAME).
9015 0x0F, // Length of domain (15)
9016 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9017 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379018 };
9019
[email protected]e0c27be2009-07-15 13:09:359020 const char kSOCKS5OkResponse[] =
9021 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9022
9023 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239024 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9025 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9026 arraysize(kSOCKS5OkRequest)),
9027 MockWrite(
9028 "GET / HTTP/1.1\r\n"
9029 "Host: www.example.org\r\n"
9030 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359031
9032 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019033 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9034 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029035 MockRead("HTTP/1.0 200 OK\r\n"),
9036 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9037 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069038 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029039 };
9040
[email protected]31a2bfe2010-02-09 08:03:399041 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9042 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079043 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029044
[email protected]8ddf8322012-02-23 18:08:069045 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079046 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029047
[email protected]49639fa2011-12-20 23:22:419048 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029049
[email protected]49639fa2011-12-20 23:22:419050 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:029051 EXPECT_EQ(ERR_IO_PENDING, rv);
9052
9053 rv = callback.WaitForResult();
9054 EXPECT_EQ(OK, rv);
9055
9056 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529057 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029058
[email protected]029c83b62013-01-24 05:28:209059 LoadTimingInfo load_timing_info;
9060 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9061 TestLoadTimingNotReusedWithPac(load_timing_info,
9062 CONNECT_TIMING_HAS_SSL_TIMES);
9063
[email protected]3cd17242009-06-23 02:59:029064 std::string response_text;
9065 rv = ReadTransaction(trans.get(), &response_text);
9066 EXPECT_EQ(OK, rv);
9067 EXPECT_EQ("Payload", response_text);
9068}
9069
[email protected]448d4ca52012-03-04 04:12:239070namespace {
9071
[email protected]04e5be32009-06-26 20:00:319072// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069073
9074struct GroupNameTest {
9075 std::string proxy_server;
9076 std::string url;
9077 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189078 bool ssl;
[email protected]2d731a32010-04-29 01:04:069079};
9080
danakj1fd259a02016-04-16 03:17:099081std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:439082 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:079083 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099084 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069085
[email protected]30d4c022013-07-18 22:58:169086 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539087 session->http_server_properties();
bnccacc0992015-03-20 20:22:229088 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:259089 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:129090 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229091 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:469092 url::SchemeHostPort("http", "host.with.alternate", 80),
9093 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069094
9095 return session;
9096}
9097
mmenkee65e7af2015-10-13 17:16:429098int GroupNameTransactionHelper(const std::string& url,
9099 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069100 HttpRequestInfo request;
9101 request.method = "GET";
9102 request.url = GURL(url);
9103 request.load_flags = 0;
9104
danakj1fd259a02016-04-16 03:17:099105 std::unique_ptr<HttpTransaction> trans(
mmenkee65e7af2015-10-13 17:16:429106 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:279107
[email protected]49639fa2011-12-20 23:22:419108 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069109
9110 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:419111 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:069112}
9113
[email protected]448d4ca52012-03-04 04:12:239114} // namespace
9115
[email protected]23e482282013-06-14 16:08:029116TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069117 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239118 {
9119 "", // unused
9120 "http://www.example.org/direct",
9121 "www.example.org:80",
9122 false,
9123 },
9124 {
9125 "", // unused
9126 "http://[2001:1418:13:1::25]/direct",
9127 "[2001:1418:13:1::25]:80",
9128 false,
9129 },
[email protected]04e5be32009-06-26 20:00:319130
bncce36dca22015-04-21 22:11:239131 // SSL Tests
9132 {
9133 "", // unused
9134 "https://www.example.org/direct_ssl",
9135 "ssl/www.example.org:443",
9136 true,
9137 },
9138 {
9139 "", // unused
9140 "https://[2001:1418:13:1::25]/direct",
9141 "ssl/[2001:1418:13:1::25]:443",
9142 true,
9143 },
9144 {
9145 "", // unused
9146 "http://host.with.alternate/direct",
9147 "ssl/host.with.alternate:443",
9148 true,
9149 },
[email protected]2d731a32010-04-29 01:04:069150 };
[email protected]2ff8b312010-04-26 22:20:549151
bncf33fb31b2016-01-29 15:22:269152 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d731a32010-04-29 01:04:069153
viettrungluue4a8b882014-10-16 06:17:389154 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039155 session_deps_.proxy_service =
9156 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099157 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:389158 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:069159
mmenkee65e7af2015-10-13 17:16:429160 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289161 CaptureGroupNameTransportSocketPool* transport_conn_pool =
9162 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139163 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349164 new CaptureGroupNameSSLSocketPool(NULL, NULL);
danakj1fd259a02016-04-16 03:17:099165 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449166 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029167 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9168 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489169 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069170
9171 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429172 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189173 if (tests[i].ssl)
9174 EXPECT_EQ(tests[i].expected_group_name,
9175 ssl_conn_pool->last_group_name_received());
9176 else
9177 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289178 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069179 }
[email protected]2d731a32010-04-29 01:04:069180}
9181
[email protected]23e482282013-06-14 16:08:029182TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069183 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239184 {
9185 "http_proxy",
9186 "http://www.example.org/http_proxy_normal",
9187 "www.example.org:80",
9188 false,
9189 },
[email protected]2d731a32010-04-29 01:04:069190
bncce36dca22015-04-21 22:11:239191 // SSL Tests
9192 {
9193 "http_proxy",
9194 "https://www.example.org/http_connect_ssl",
9195 "ssl/www.example.org:443",
9196 true,
9197 },
[email protected]af3490e2010-10-16 21:02:299198
bncce36dca22015-04-21 22:11:239199 {
9200 "http_proxy",
9201 "http://host.with.alternate/direct",
9202 "ssl/host.with.alternate:443",
9203 true,
9204 },
[email protected]45499252013-01-23 17:12:569205
bncce36dca22015-04-21 22:11:239206 {
9207 "http_proxy",
9208 "ftp://ftp.google.com/http_proxy_normal",
9209 "ftp/ftp.google.com:21",
9210 false,
9211 },
[email protected]2d731a32010-04-29 01:04:069212 };
9213
bncf33fb31b2016-01-29 15:22:269214 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d731a32010-04-29 01:04:069215
viettrungluue4a8b882014-10-16 06:17:389216 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039217 session_deps_.proxy_service =
9218 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099219 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:389220 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:069221
mmenkee65e7af2015-10-13 17:16:429222 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069223
[email protected]e60e47a2010-07-14 03:37:189224 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139225 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349226 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139227 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349228 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029229
danakj1fd259a02016-04-16 03:17:099230 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449231 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029232 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
9233 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489234 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069235
9236 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429237 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189238 if (tests[i].ssl)
9239 EXPECT_EQ(tests[i].expected_group_name,
9240 ssl_conn_pool->last_group_name_received());
9241 else
9242 EXPECT_EQ(tests[i].expected_group_name,
9243 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069244 }
[email protected]2d731a32010-04-29 01:04:069245}
9246
[email protected]23e482282013-06-14 16:08:029247TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069248 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239249 {
9250 "socks4://socks_proxy:1080",
9251 "http://www.example.org/socks4_direct",
9252 "socks4/www.example.org:80",
9253 false,
9254 },
9255 {
9256 "socks5://socks_proxy:1080",
9257 "http://www.example.org/socks5_direct",
9258 "socks5/www.example.org:80",
9259 false,
9260 },
[email protected]2d731a32010-04-29 01:04:069261
bncce36dca22015-04-21 22:11:239262 // SSL Tests
9263 {
9264 "socks4://socks_proxy:1080",
9265 "https://www.example.org/socks4_ssl",
9266 "socks4/ssl/www.example.org:443",
9267 true,
9268 },
9269 {
9270 "socks5://socks_proxy:1080",
9271 "https://www.example.org/socks5_ssl",
9272 "socks5/ssl/www.example.org:443",
9273 true,
9274 },
[email protected]af3490e2010-10-16 21:02:299275
bncce36dca22015-04-21 22:11:239276 {
9277 "socks4://socks_proxy:1080",
9278 "http://host.with.alternate/direct",
9279 "socks4/ssl/host.with.alternate:443",
9280 true,
9281 },
[email protected]04e5be32009-06-26 20:00:319282 };
9283
bncf33fb31b2016-01-29 15:22:269284 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2ff8b312010-04-26 22:20:549285
viettrungluue4a8b882014-10-16 06:17:389286 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039287 session_deps_.proxy_service =
9288 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099289 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:389290 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:029291
mmenkee65e7af2015-10-13 17:16:429292 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319293
[email protected]e60e47a2010-07-14 03:37:189294 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139295 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349296 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139297 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349298 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029299
danakj1fd259a02016-04-16 03:17:099300 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449301 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029302 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
9303 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489304 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319305
danakj1fd259a02016-04-16 03:17:099306 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:319308
[email protected]2d731a32010-04-29 01:04:069309 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429310 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189311 if (tests[i].ssl)
9312 EXPECT_EQ(tests[i].expected_group_name,
9313 ssl_conn_pool->last_group_name_received());
9314 else
9315 EXPECT_EQ(tests[i].expected_group_name,
9316 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319317 }
9318}
9319
[email protected]23e482282013-06-14 16:08:029320TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279321 HttpRequestInfo request;
9322 request.method = "GET";
bncce36dca22015-04-21 22:11:239323 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279324
rdsmith82957ad2015-09-16 19:42:039325 session_deps_.proxy_service =
9326 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329327
[email protected]69719062010-01-05 20:09:219328 // This simulates failure resolving all hostnames; that means we will fail
9329 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079330 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329331
danakj1fd259a02016-04-16 03:17:099332 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9333 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419334 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:259335
[email protected]49639fa2011-12-20 23:22:419336 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259337
[email protected]49639fa2011-12-20 23:22:419338 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:259339 EXPECT_EQ(ERR_IO_PENDING, rv);
9340
[email protected]9172a982009-06-06 00:30:259341 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:019342 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:259343}
9344
[email protected]685af592010-05-11 19:31:249345// Base test to make sure that when the load flags for a request specify to
9346// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029347void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079348 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279349 // Issue a request, asking to bypass the cache(s).
9350 HttpRequestInfo request;
9351 request.method = "GET";
9352 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:239353 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279354
[email protected]a2c2fb92009-07-18 07:31:049355 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:079356 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:329357
danakj1fd259a02016-04-16 03:17:099358 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9359 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419360 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:289361
bncce36dca22015-04-21 22:11:239362 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289363 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299364 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:079365 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239366 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
9367 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:479368 EXPECT_EQ(ERR_IO_PENDING, rv);
9369 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289370 EXPECT_EQ(OK, rv);
9371
9372 // Verify that it was added to host cache, by doing a subsequent async lookup
9373 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:079374 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239375 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
9376 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:329377 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:289378
bncce36dca22015-04-21 22:11:239379 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289380 // we can tell if the next lookup hit the cache, or the "network".
9381 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239382 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289383
9384 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9385 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069386 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399387 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079388 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289389
[email protected]3b9cca42009-06-16 01:08:289390 // Run the request.
[email protected]49639fa2011-12-20 23:22:419391 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:289392 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419393 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289394
9395 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239396 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289397 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
9398}
9399
[email protected]685af592010-05-11 19:31:249400// There are multiple load flags that should trigger the host cache bypass.
9401// Test each in isolation:
[email protected]23e482282013-06-14 16:08:029402TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249403 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9404}
9405
[email protected]23e482282013-06-14 16:08:029406TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249407 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9408}
9409
[email protected]23e482282013-06-14 16:08:029410TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249411 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9412}
9413
[email protected]0877e3d2009-10-17 22:29:579414// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:029415TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579416 HttpRequestInfo request;
9417 request.method = "GET";
9418 request.url = GURL("http://www.foo.com/");
9419 request.load_flags = 0;
9420
9421 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069422 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579423 };
[email protected]31a2bfe2010-02-09 08:03:399424 StaticSocketDataProvider data(NULL, 0,
9425 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079426 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099427 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579428
[email protected]49639fa2011-12-20 23:22:419429 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579430
danakj1fd259a02016-04-16 03:17:099431 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419432 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579433
[email protected]49639fa2011-12-20 23:22:419434 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579435 EXPECT_EQ(ERR_IO_PENDING, rv);
9436
9437 rv = callback.WaitForResult();
9438 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:599439
9440 IPEndPoint endpoint;
9441 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
9442 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579443}
9444
zmo9528c9f42015-08-04 22:12:089445// Check that a connection closed after the start of the headers finishes ok.
9446TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579447 HttpRequestInfo request;
9448 request.method = "GET";
9449 request.url = GURL("http://www.foo.com/");
9450 request.load_flags = 0;
9451
9452 MockRead data_reads[] = {
9453 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069454 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579455 };
9456
[email protected]31a2bfe2010-02-09 08:03:399457 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079458 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099459 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579460
[email protected]49639fa2011-12-20 23:22:419461 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579462
danakj1fd259a02016-04-16 03:17:099463 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419464 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579465
[email protected]49639fa2011-12-20 23:22:419466 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579467 EXPECT_EQ(ERR_IO_PENDING, rv);
9468
9469 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:089470 EXPECT_EQ(OK, rv);
9471
9472 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529473 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089474
wezca1070932016-05-26 20:30:529475 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089476 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9477
9478 std::string response_data;
9479 rv = ReadTransaction(trans.get(), &response_data);
9480 EXPECT_EQ(OK, rv);
9481 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599482
9483 IPEndPoint endpoint;
9484 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
9485 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579486}
9487
9488// Make sure that a dropped connection while draining the body for auth
9489// restart does the right thing.
[email protected]23e482282013-06-14 16:08:029490TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579491 HttpRequestInfo request;
9492 request.method = "GET";
bncce36dca22015-04-21 22:11:239493 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579494 request.load_flags = 0;
9495
9496 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239497 MockWrite(
9498 "GET / HTTP/1.1\r\n"
9499 "Host: www.example.org\r\n"
9500 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579501 };
9502
9503 MockRead data_reads1[] = {
9504 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9505 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9506 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9507 MockRead("Content-Length: 14\r\n\r\n"),
9508 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069509 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579510 };
9511
[email protected]31a2bfe2010-02-09 08:03:399512 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9513 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079514 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579515
9516 // After calling trans->RestartWithAuth(), this is the request we should
9517 // be issuing -- the final header line contains the credentials.
9518 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239519 MockWrite(
9520 "GET / HTTP/1.1\r\n"
9521 "Host: www.example.org\r\n"
9522 "Connection: keep-alive\r\n"
9523 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579524 };
9525
9526 // Lastly, the server responds with the actual content.
9527 MockRead data_reads2[] = {
9528 MockRead("HTTP/1.1 200 OK\r\n"),
9529 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9530 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069531 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579532 };
9533
[email protected]31a2bfe2010-02-09 08:03:399534 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9535 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079536 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099537 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579538
[email protected]49639fa2011-12-20 23:22:419539 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579540
danakj1fd259a02016-04-16 03:17:099541 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509542 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509543
[email protected]49639fa2011-12-20 23:22:419544 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579545 EXPECT_EQ(ERR_IO_PENDING, rv);
9546
9547 rv = callback1.WaitForResult();
9548 EXPECT_EQ(OK, rv);
9549
9550 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529551 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049552 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579553
[email protected]49639fa2011-12-20 23:22:419554 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579555
[email protected]49639fa2011-12-20 23:22:419556 rv = trans->RestartWithAuth(
9557 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:579558 EXPECT_EQ(ERR_IO_PENDING, rv);
9559
9560 rv = callback2.WaitForResult();
9561 EXPECT_EQ(OK, rv);
9562
9563 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529564 ASSERT_TRUE(response);
9565 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579566 EXPECT_EQ(100, response->headers->GetContentLength());
9567}
9568
9569// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:029570TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039571 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579572
9573 HttpRequestInfo request;
9574 request.method = "GET";
bncce36dca22015-04-21 22:11:239575 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579576 request.load_flags = 0;
9577
9578 MockRead proxy_reads[] = {
9579 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069580 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579581 };
9582
[email protected]31a2bfe2010-02-09 08:03:399583 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069584 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579585
[email protected]bb88e1d32013-05-03 23:11:079586 session_deps_.socket_factory->AddSocketDataProvider(&data);
9587 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579588
[email protected]49639fa2011-12-20 23:22:419589 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579590
[email protected]bb88e1d32013-05-03 23:11:079591 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579592
danakj1fd259a02016-04-16 03:17:099593 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9594 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419595 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579596
[email protected]49639fa2011-12-20 23:22:419597 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579598 EXPECT_EQ(ERR_IO_PENDING, rv);
9599
9600 rv = callback.WaitForResult();
9601 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
9602}
9603
[email protected]23e482282013-06-14 16:08:029604TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469605 HttpRequestInfo request;
9606 request.method = "GET";
bncce36dca22015-04-21 22:11:239607 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469608 request.load_flags = 0;
9609
danakj1fd259a02016-04-16 03:17:099610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9611 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419612 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:279613
[email protected]e22e1362009-11-23 21:31:129614 MockRead data_reads[] = {
9615 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069616 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129617 };
[email protected]9492e4a2010-02-24 00:58:469618
9619 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079620 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469621
[email protected]49639fa2011-12-20 23:22:419622 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469623
[email protected]49639fa2011-12-20 23:22:419624 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:469625 EXPECT_EQ(ERR_IO_PENDING, rv);
9626
9627 EXPECT_EQ(OK, callback.WaitForResult());
9628
9629 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529630 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469631
wezca1070932016-05-26 20:30:529632 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469633 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9634
9635 std::string response_data;
9636 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:239637 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:129638}
9639
[email protected]23e482282013-06-14 16:08:029640TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159641 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529642 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149643 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219644 UploadFileElementReader::ScopedOverridingContentLengthForTests
9645 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339646
danakj1fd259a02016-04-16 03:17:099647 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9648 element_readers.push_back(base::WrapUnique(new UploadFileElementReader(
avibf0746c2015-12-09 19:53:149649 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
9650 std::numeric_limits<uint64_t>::max(), base::Time())));
olli.raula6df48b2a2015-11-26 07:40:229651 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279652
9653 HttpRequestInfo request;
9654 request.method = "POST";
bncce36dca22015-04-21 22:11:239655 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279656 request.upload_data_stream = &upload_data_stream;
9657 request.load_flags = 0;
9658
danakj1fd259a02016-04-16 03:17:099659 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9660 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419661 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:339662
9663 MockRead data_reads[] = {
9664 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9665 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069666 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339667 };
[email protected]31a2bfe2010-02-09 08:03:399668 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079669 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339670
[email protected]49639fa2011-12-20 23:22:419671 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339672
[email protected]49639fa2011-12-20 23:22:419673 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:339674 EXPECT_EQ(ERR_IO_PENDING, rv);
9675
9676 rv = callback.WaitForResult();
9677 EXPECT_EQ(OK, rv);
9678
9679 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529680 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339681
wezca1070932016-05-26 20:30:529682 EXPECT_TRUE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339683 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9684
9685 std::string response_data;
9686 rv = ReadTransaction(trans.get(), &response_data);
9687 EXPECT_EQ(OK, rv);
9688 EXPECT_EQ("hello world", response_data);
9689
[email protected]dd3aa792013-07-16 19:10:239690 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339691}
9692
[email protected]23e482282013-06-14 16:08:029693TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159694 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529695 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369696 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309697 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369698 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119699 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369700
danakj1fd259a02016-04-16 03:17:099701 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9702 element_readers.push_back(base::WrapUnique(new UploadFileElementReader(
avibf0746c2015-12-09 19:53:149703 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
9704 std::numeric_limits<uint64_t>::max(), base::Time())));
olli.raula6df48b2a2015-11-26 07:40:229705 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279706
9707 HttpRequestInfo request;
9708 request.method = "POST";
bncce36dca22015-04-21 22:11:239709 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279710 request.upload_data_stream = &upload_data_stream;
9711 request.load_flags = 0;
9712
[email protected]999dd8c2013-11-12 06:45:549713 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099714 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9715 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419716 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:369717
[email protected]999dd8c2013-11-12 06:45:549718 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079719 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369720
[email protected]49639fa2011-12-20 23:22:419721 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369722
[email protected]49639fa2011-12-20 23:22:419723 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:369724 EXPECT_EQ(ERR_IO_PENDING, rv);
9725
9726 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:549727 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:369728
[email protected]dd3aa792013-07-16 19:10:239729 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369730}
9731
[email protected]02cad5d2013-10-02 08:14:039732TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
9733 class FakeUploadElementReader : public UploadElementReader {
9734 public:
9735 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209736 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039737
9738 const CompletionCallback& callback() const { return callback_; }
9739
9740 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209741 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039742 callback_ = callback;
9743 return ERR_IO_PENDING;
9744 }
avibf0746c2015-12-09 19:53:149745 uint64_t GetContentLength() const override { return 0; }
9746 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209747 int Read(IOBuffer* buf,
9748 int buf_length,
9749 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039750 return ERR_FAILED;
9751 }
9752
9753 private:
9754 CompletionCallback callback_;
9755 };
9756
9757 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099758 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9759 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229760 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039761
9762 HttpRequestInfo request;
9763 request.method = "POST";
bncce36dca22015-04-21 22:11:239764 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039765 request.upload_data_stream = &upload_data_stream;
9766 request.load_flags = 0;
9767
danakj1fd259a02016-04-16 03:17:099768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9769 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039771
9772 StaticSocketDataProvider data;
9773 session_deps_.socket_factory->AddSocketDataProvider(&data);
9774
9775 TestCompletionCallback callback;
9776 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9777 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:559778 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039779
9780 // Transaction is pending on request body initialization.
9781 ASSERT_FALSE(fake_reader->callback().is_null());
9782
9783 // Return Init()'s result after the transaction gets destroyed.
9784 trans.reset();
9785 fake_reader->callback().Run(OK); // Should not crash.
9786}
9787
[email protected]aeefc9e82010-02-19 16:18:279788// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:029789TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279790 HttpRequestInfo request;
9791 request.method = "GET";
bncce36dca22015-04-21 22:11:239792 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279793 request.load_flags = 0;
9794
9795 // First transaction will request a resource and receive a Basic challenge
9796 // with realm="first_realm".
9797 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239798 MockWrite(
9799 "GET / HTTP/1.1\r\n"
9800 "Host: www.example.org\r\n"
9801 "Connection: keep-alive\r\n"
9802 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279803 };
9804 MockRead data_reads1[] = {
9805 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9806 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9807 "\r\n"),
9808 };
9809
9810 // After calling trans->RestartWithAuth(), provide an Authentication header
9811 // for first_realm. The server will reject and provide a challenge with
9812 // second_realm.
9813 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239814 MockWrite(
9815 "GET / HTTP/1.1\r\n"
9816 "Host: www.example.org\r\n"
9817 "Connection: keep-alive\r\n"
9818 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9819 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279820 };
9821 MockRead data_reads2[] = {
9822 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9823 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9824 "\r\n"),
9825 };
9826
9827 // This again fails, and goes back to first_realm. Make sure that the
9828 // entry is removed from cache.
9829 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239830 MockWrite(
9831 "GET / HTTP/1.1\r\n"
9832 "Host: www.example.org\r\n"
9833 "Connection: keep-alive\r\n"
9834 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9835 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279836 };
9837 MockRead data_reads3[] = {
9838 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9839 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9840 "\r\n"),
9841 };
9842
9843 // Try one last time (with the correct password) and get the resource.
9844 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239845 MockWrite(
9846 "GET / HTTP/1.1\r\n"
9847 "Host: www.example.org\r\n"
9848 "Connection: keep-alive\r\n"
9849 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9850 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279851 };
9852 MockRead data_reads4[] = {
9853 MockRead("HTTP/1.1 200 OK\r\n"
9854 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509855 "Content-Length: 5\r\n"
9856 "\r\n"
9857 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279858 };
9859
9860 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9861 data_writes1, arraysize(data_writes1));
9862 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9863 data_writes2, arraysize(data_writes2));
9864 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9865 data_writes3, arraysize(data_writes3));
9866 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9867 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079868 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9869 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9870 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9871 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279872
[email protected]49639fa2011-12-20 23:22:419873 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279874
danakj1fd259a02016-04-16 03:17:099875 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9876 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419877 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509878
[email protected]aeefc9e82010-02-19 16:18:279879 // Issue the first request with Authorize headers. There should be a
9880 // password prompt for first_realm waiting to be filled in after the
9881 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419882 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:279883 EXPECT_EQ(ERR_IO_PENDING, rv);
9884 rv = callback1.WaitForResult();
9885 EXPECT_EQ(OK, rv);
9886 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529887 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049888 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529889 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049890 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239891 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049892 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199893 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279894
9895 // Issue the second request with an incorrect password. There should be a
9896 // password prompt for second_realm waiting to be filled in after the
9897 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419898 TestCompletionCallback callback2;
9899 rv = trans->RestartWithAuth(
9900 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:279901 EXPECT_EQ(ERR_IO_PENDING, rv);
9902 rv = callback2.WaitForResult();
9903 EXPECT_EQ(OK, rv);
9904 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529905 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049906 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529907 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049908 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239909 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049910 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199911 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279912
9913 // Issue the third request with another incorrect password. There should be
9914 // a password prompt for first_realm waiting to be filled in. If the password
9915 // prompt is not present, it indicates that the HttpAuthCacheEntry for
9916 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:419917 TestCompletionCallback callback3;
9918 rv = trans->RestartWithAuth(
9919 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:279920 EXPECT_EQ(ERR_IO_PENDING, rv);
9921 rv = callback3.WaitForResult();
9922 EXPECT_EQ(OK, rv);
9923 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529924 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049925 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529926 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049927 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239928 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049929 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199930 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279931
9932 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:419933 TestCompletionCallback callback4;
9934 rv = trans->RestartWithAuth(
9935 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:279936 EXPECT_EQ(ERR_IO_PENDING, rv);
9937 rv = callback4.WaitForResult();
9938 EXPECT_EQ(OK, rv);
9939 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529940 ASSERT_TRUE(response);
9941 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:279942}
9943
bncc958faa2015-07-31 18:14:529944TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:269945 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:529946
9947 std::string alternative_service_http_header =
9948 GetAlternativeServiceHttpHeader();
9949
9950 MockRead data_reads[] = {
9951 MockRead("HTTP/1.1 200 OK\r\n"),
9952 MockRead(alternative_service_http_header.c_str()),
9953 MockRead("\r\n"),
9954 MockRead("hello world"),
9955 MockRead(SYNCHRONOUS, OK),
9956 };
9957
9958 HttpRequestInfo request;
9959 request.method = "GET";
9960 request.url = GURL("http://www.example.org/");
9961 request.load_flags = 0;
9962
9963 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9964
9965 session_deps_.socket_factory->AddSocketDataProvider(&data);
9966
9967 TestCompletionCallback callback;
9968
danakj1fd259a02016-04-16 03:17:099969 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9970 std::unique_ptr<HttpTransaction> trans(
bncc958faa2015-07-31 18:14:529971 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9972
9973 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9974 EXPECT_EQ(ERR_IO_PENDING, rv);
9975
zhongyi3d4a55e72016-04-22 20:36:469976 url::SchemeHostPort test_server("http", "www.example.org", 80);
bncc958faa2015-07-31 18:14:529977 HttpServerProperties& http_server_properties =
9978 *session->http_server_properties();
9979 AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469980 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529981 EXPECT_TRUE(alternative_service_vector.empty());
9982
9983 EXPECT_EQ(OK, callback.WaitForResult());
9984
9985 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529986 ASSERT_TRUE(response);
9987 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:529988 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9989 EXPECT_FALSE(response->was_fetched_via_spdy);
9990 EXPECT_FALSE(response->was_npn_negotiated);
9991
9992 std::string response_data;
9993 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9994 EXPECT_EQ("hello world", response_data);
9995
9996 alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:469997 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529998 ASSERT_EQ(1u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:389999 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:5210000 alternative_service_vector[0].protocol);
bnc8bef8da22016-05-30 01:28:2510001 EXPECT_EQ("www.example.org", alternative_service_vector[0].host);
bncc958faa2015-07-31 18:14:5210002 EXPECT_EQ(443, alternative_service_vector[0].port);
10003}
10004
bnce3dd56f2016-06-01 10:37:1110005// Regression test for https://crbug.com/615497.
10006TEST_P(HttpNetworkTransactionTest,
10007 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
10008 session_deps_.enable_alternative_service_for_insecure_origins = false;
10009
10010 std::string alternative_service_http_header =
10011 GetAlternativeServiceHttpHeader();
10012
10013 MockRead data_reads[] = {
10014 MockRead("HTTP/1.1 200 OK\r\n"),
10015 MockRead(alternative_service_http_header.c_str()),
10016 MockRead("\r\n"),
10017 MockRead("hello world"),
10018 MockRead(SYNCHRONOUS, OK),
10019 };
10020
10021 HttpRequestInfo request;
10022 request.method = "GET";
10023 request.url = GURL("http://www.example.org/");
10024 request.load_flags = 0;
10025
10026 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10027 session_deps_.socket_factory->AddSocketDataProvider(&data);
10028
10029 TestCompletionCallback callback;
10030
10031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10032 std::unique_ptr<HttpTransaction> trans(
10033 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10034
10035 url::SchemeHostPort test_server(request.url);
10036 HttpServerProperties& http_server_properties =
10037 *session->http_server_properties();
10038 AlternativeServiceVector alternative_service_vector =
10039 http_server_properties.GetAlternativeServices(test_server);
10040 EXPECT_TRUE(alternative_service_vector.empty());
10041
10042 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10043 EXPECT_EQ(ERR_IO_PENDING, rv);
10044 EXPECT_EQ(OK, callback.WaitForResult());
10045
10046 const HttpResponseInfo* response = trans->GetResponseInfo();
10047 ASSERT_TRUE(response);
10048 ASSERT_TRUE(response->headers);
10049 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10050 EXPECT_FALSE(response->was_fetched_via_spdy);
10051 EXPECT_FALSE(response->was_npn_negotiated);
10052
10053 std::string response_data;
10054 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10055 EXPECT_EQ("hello world", response_data);
10056
10057 alternative_service_vector =
10058 http_server_properties.GetAlternativeServices(test_server);
10059 EXPECT_TRUE(alternative_service_vector.empty());
10060}
10061
bnc8bef8da22016-05-30 01:28:2510062// HTTP/2 Alternative Services should be disabled if alternative service
10063// hostname is different from that of origin.
10064// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
10065TEST_P(HttpNetworkTransactionTest,
10066 DisableHTTP2AlternativeServicesWithDifferentHost) {
10067 session_deps_.enable_alternative_service_with_different_host = true;
10068
10069 HttpRequestInfo request;
10070 request.method = "GET";
10071 request.url = GURL("http://www.example.org/");
10072 request.load_flags = 0;
10073
10074 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10075 StaticSocketDataProvider first_data;
10076 first_data.set_connect_data(mock_connect);
10077 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10078
10079 MockRead data_reads[] = {
10080 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10081 MockRead(ASYNC, OK),
10082 };
10083 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10084 0);
10085 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10086
10087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10088
10089 base::WeakPtr<HttpServerProperties> http_server_properties =
10090 session->http_server_properties();
10091 AlternativeService alternative_service(
10092 AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
10093 444);
10094 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10095 http_server_properties->SetAlternativeService(
10096 url::SchemeHostPort(request.url), alternative_service, expiration);
10097
10098 std::unique_ptr<HttpTransaction> trans(
10099 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10100 TestCompletionCallback callback;
10101
10102 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10103 // Alternative service is not used, request fails.
10104 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
10105}
10106
bnce3dd56f2016-06-01 10:37:1110107// Regression test for https://crbug.com/615497:
10108// Alternative Services should be disabled for http origin.
10109TEST_P(HttpNetworkTransactionTest,
10110 DisableAlternativeServicesForInsecureOrigin) {
10111 session_deps_.enable_alternative_service_for_insecure_origins = false;
10112
10113 HttpRequestInfo request;
10114 request.method = "GET";
10115 request.url = GURL("http://www.example.org/");
10116 request.load_flags = 0;
10117
10118 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10119 StaticSocketDataProvider first_data;
10120 first_data.set_connect_data(mock_connect);
10121 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10122
10123 MockRead data_reads[] = {
10124 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10125 MockRead(ASYNC, OK),
10126 };
10127 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10128 0);
10129 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10130
10131 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10132
10133 base::WeakPtr<HttpServerProperties> http_server_properties =
10134 session->http_server_properties();
10135 AlternativeService alternative_service(
10136 AlternateProtocolFromNextProto(GetProtocol()), "", 444);
10137 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10138 http_server_properties->SetAlternativeService(
10139 url::SchemeHostPort(request.url), alternative_service, expiration);
10140
10141 std::unique_ptr<HttpTransaction> trans(
10142 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10143 TestCompletionCallback callback;
10144
10145 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10146 // Alternative service is not used, request fails.
10147 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
10148}
10149
bnc4f575852015-10-14 18:35:0810150TEST_P(HttpNetworkTransactionTest, ClearAlternativeServices) {
bncf33fb31b2016-01-29 15:22:2610151 session_deps_.enable_alternative_service_with_different_host = false;
bnc4f575852015-10-14 18:35:0810152
10153 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910154 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc4f575852015-10-14 18:35:0810155 HttpServerProperties& http_server_properties =
10156 *session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610157 url::SchemeHostPort test_server("http", "www.example.org", 80);
bnc4f575852015-10-14 18:35:0810158 AlternativeService alternative_service(QUIC, "", 80);
10159 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610160 http_server_properties.SetAlternativeService(test_server, alternative_service,
10161 expiration);
bnc4f575852015-10-14 18:35:0810162 AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610163 http_server_properties.GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810164 EXPECT_EQ(1u, alternative_service_vector.size());
10165
10166 // Send a clear header.
10167 MockRead data_reads[] = {
10168 MockRead("HTTP/1.1 200 OK\r\n"),
10169 MockRead("Alt-Svc: clear\r\n"),
10170 MockRead("\r\n"),
10171 MockRead("hello world"),
10172 MockRead(SYNCHRONOUS, OK),
10173 };
10174 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10175 session_deps_.socket_factory->AddSocketDataProvider(&data);
10176
10177 HttpRequestInfo request;
10178 request.method = "GET";
10179 request.url = GURL("http://www.example.org/");
10180 request.load_flags = 0;
10181
10182 TestCompletionCallback callback;
10183
danakj1fd259a02016-04-16 03:17:0910184 std::unique_ptr<HttpTransaction> trans(
bnc4f575852015-10-14 18:35:0810185 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10186
10187 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10188 EXPECT_EQ(OK, callback.GetResult(rv));
10189
10190 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210191 ASSERT_TRUE(response);
10192 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810193 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10194 EXPECT_FALSE(response->was_fetched_via_spdy);
10195 EXPECT_FALSE(response->was_npn_negotiated);
10196
10197 std::string response_data;
10198 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10199 EXPECT_EQ("hello world", response_data);
10200
10201 alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610202 http_server_properties.GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810203 EXPECT_TRUE(alternative_service_vector.empty());
10204}
10205
bncc958faa2015-07-31 18:14:5210206TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:2610207 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:5210208
10209 MockRead data_reads[] = {
10210 MockRead("HTTP/1.1 200 OK\r\n"),
10211 MockRead("Alt-Svc: "),
10212 MockRead(GetAlternateProtocolFromParam()),
bnc44858c82015-10-16 11:57:2110213 MockRead("=\"www.example.com:443\";p=\"1.0\","),
bnc3f0118e2016-02-02 15:42:2210214 MockRead(GetAlternateProtocolFromParam()),
10215 MockRead("=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210216 MockRead("hello world"),
10217 MockRead(SYNCHRONOUS, OK),
10218 };
10219
10220 HttpRequestInfo request;
10221 request.method = "GET";
10222 request.url = GURL("http://www.example.org/");
10223 request.load_flags = 0;
10224
10225 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10226
10227 session_deps_.socket_factory->AddSocketDataProvider(&data);
10228
10229 TestCompletionCallback callback;
10230
danakj1fd259a02016-04-16 03:17:0910231 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10232 std::unique_ptr<HttpTransaction> trans(
bncc958faa2015-07-31 18:14:5210233 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10234
10235 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10236 EXPECT_EQ(ERR_IO_PENDING, rv);
10237
zhongyi3d4a55e72016-04-22 20:36:4610238 url::SchemeHostPort test_server("http", "www.example.org", 80);
bncc958faa2015-07-31 18:14:5210239 HttpServerProperties& http_server_properties =
10240 *session->http_server_properties();
10241 AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610242 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210243 EXPECT_TRUE(alternative_service_vector.empty());
10244
10245 EXPECT_EQ(OK, callback.WaitForResult());
10246
10247 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210248 ASSERT_TRUE(response);
10249 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210250 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10251 EXPECT_FALSE(response->was_fetched_via_spdy);
10252 EXPECT_FALSE(response->was_npn_negotiated);
10253
10254 std::string response_data;
10255 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10256 EXPECT_EQ("hello world", response_data);
10257
10258 alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610259 http_server_properties.GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210260 ASSERT_EQ(2u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:3810261 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:5210262 alternative_service_vector[0].protocol);
10263 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
10264 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc3f0118e2016-02-02 15:42:2210265 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
10266 alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:5210267 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
10268 EXPECT_EQ(1234, alternative_service_vector[1].port);
10269}
10270
bncf33fb31b2016-01-29 15:22:2610271// When |enable_alternative_service_with_different_host| is false, do not
10272// observe alternative service entries that point to a different host.
bnc54ec34b72015-08-26 19:34:5610273TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
bncf33fb31b2016-01-29 15:22:2610274 session_deps_.enable_alternative_service_with_different_host = false;
bnc54ec34b72015-08-26 19:34:5610275
10276 HttpRequestInfo request;
10277 request.method = "GET";
10278 request.url = GURL("http://www.example.org/");
10279 request.load_flags = 0;
10280
10281 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10282 StaticSocketDataProvider first_data;
10283 first_data.set_connect_data(mock_connect);
10284 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10285
10286 MockRead data_reads[] = {
10287 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10288 MockRead(ASYNC, OK),
10289 };
10290 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
10291 nullptr, 0);
10292 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10293
danakj1fd259a02016-04-16 03:17:0910294 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:5610295
10296 base::WeakPtr<HttpServerProperties> http_server_properties =
10297 session->http_server_properties();
10298 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810299 AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
10300 80);
bnc54ec34b72015-08-26 19:34:5610301 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10302 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610303 url::SchemeHostPort(request.url), alternative_service, expiration);
bnc54ec34b72015-08-26 19:34:5610304
danakj1fd259a02016-04-16 03:17:0910305 std::unique_ptr<HttpTransaction> trans(
bnc54ec34b72015-08-26 19:34:5610306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10307 TestCompletionCallback callback;
10308
10309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10310 // The connetion to origin was refused, and the alternative service should not
10311 // be used (even though mock data are there), therefore the request should
10312 // fail.
10313 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
10314}
10315
zhongyi48704c182015-12-07 07:52:0210316TEST_P(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610317 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210318 HostPortPair alternative("alternative.example.org", 443);
10319 std::string origin_url = "https://origin.example.org:443";
10320 std::string alternative_url = "https://alternative.example.org:443";
10321
10322 // Negotiate HTTP/1.1 with alternative.example.org.
10323 SSLSocketDataProvider ssl(ASYNC, OK);
10324 ssl.SetNextProto(kProtoHTTP11);
10325 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10326
10327 // HTTP/1.1 data for request.
10328 MockWrite http_writes[] = {
10329 MockWrite("GET / HTTP/1.1\r\n"
10330 "Host: alternative.example.org\r\n"
10331 "Connection: keep-alive\r\n\r\n"),
10332 };
10333
10334 MockRead http_reads[] = {
10335 MockRead("HTTP/1.1 200 OK\r\n"
10336 "Content-Type: text/html; charset=iso-8859-1\r\n"
10337 "Content-Length: 40\r\n\r\n"
10338 "first HTTP/1.1 response from alternative"),
10339 };
10340 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10341 http_writes, arraysize(http_writes));
10342 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10343
10344 StaticSocketDataProvider data_refused;
10345 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10346 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10347
zhongyi3d4a55e72016-04-22 20:36:4610348 // Set up a QUIC alternative service for server.
bncf33fb31b2016-01-29 15:22:2610349 session_deps_.enable_alternative_service_with_different_host = false;
danakj1fd259a02016-04-16 03:17:0910350 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zhongyi48704c182015-12-07 07:52:0210351 base::WeakPtr<HttpServerProperties> http_server_properties =
10352 session->http_server_properties();
10353 AlternativeService alternative_service(QUIC, alternative);
10354 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610355 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010356 expiration);
zhongyi48704c182015-12-07 07:52:0210357 // Mark the QUIC alternative service as broken.
10358 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10359
danakj1fd259a02016-04-16 03:17:0910360 std::unique_ptr<HttpTransaction> trans(
zhongyi48704c182015-12-07 07:52:0210361 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10362 HttpRequestInfo request;
10363 request.method = "GET";
10364 request.url = GURL(origin_url);
10365 request.load_flags = 0;
10366 TestCompletionCallback callback;
10367 NetErrorDetails details;
10368 EXPECT_FALSE(details.quic_broken);
10369
10370 trans->Start(&request, callback.callback(), BoundNetLog());
10371 trans->PopulateNetErrorDetails(&details);
10372 EXPECT_TRUE(details.quic_broken);
10373}
10374
10375TEST_P(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610376 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210377 HostPortPair alternative1("alternative1.example.org", 443);
10378 HostPortPair alternative2("alternative2.example.org", 443);
10379 std::string origin_url = "https://origin.example.org:443";
10380 std::string alternative_url1 = "https://alternative1.example.org:443";
10381 std::string alternative_url2 = "https://alternative2.example.org:443";
10382
10383 // Negotiate HTTP/1.1 with alternative1.example.org.
10384 SSLSocketDataProvider ssl(ASYNC, OK);
10385 ssl.SetNextProto(kProtoHTTP11);
10386 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10387
10388 // HTTP/1.1 data for request.
10389 MockWrite http_writes[] = {
10390 MockWrite("GET / HTTP/1.1\r\n"
10391 "Host: alternative1.example.org\r\n"
10392 "Connection: keep-alive\r\n\r\n"),
10393 };
10394
10395 MockRead http_reads[] = {
10396 MockRead("HTTP/1.1 200 OK\r\n"
10397 "Content-Type: text/html; charset=iso-8859-1\r\n"
10398 "Content-Length: 40\r\n\r\n"
10399 "first HTTP/1.1 response from alternative1"),
10400 };
10401 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10402 http_writes, arraysize(http_writes));
10403 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10404
10405 StaticSocketDataProvider data_refused;
10406 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10407 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10408
bncf33fb31b2016-01-29 15:22:2610409 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0910410 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zhongyi48704c182015-12-07 07:52:0210411 base::WeakPtr<HttpServerProperties> http_server_properties =
10412 session->http_server_properties();
10413
zhongyi3d4a55e72016-04-22 20:36:4610414 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210415 AlternativeServiceInfoVector alternative_service_info_vector;
10416 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10417
10418 AlternativeService alternative_service1(QUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010419 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210420 expiration);
10421 alternative_service_info_vector.push_back(alternative_service_info1);
10422 AlternativeService alternative_service2(QUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010423 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210424 expiration);
10425 alternative_service_info_vector.push_back(alternative_service_info2);
10426
10427 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610428 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210429
10430 // Mark one of the QUIC alternative service as broken.
10431 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10432
10433 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610434 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:0210435
danakj1fd259a02016-04-16 03:17:0910436 std::unique_ptr<HttpTransaction> trans(
zhongyi48704c182015-12-07 07:52:0210437 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10438 HttpRequestInfo request;
10439 request.method = "GET";
10440 request.url = GURL(origin_url);
10441 request.load_flags = 0;
10442 TestCompletionCallback callback;
10443 NetErrorDetails details;
10444 EXPECT_FALSE(details.quic_broken);
10445
10446 trans->Start(&request, callback.callback(), BoundNetLog());
10447 trans->PopulateNetErrorDetails(&details);
10448 EXPECT_FALSE(details.quic_broken);
10449}
10450
[email protected]23e482282013-06-14 16:08:0210451TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310452 MarkBrokenAlternateProtocolAndFallback) {
bncf33fb31b2016-01-29 15:22:2610453 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]564b4912010-03-09 16:30:4210454
10455 HttpRequestInfo request;
10456 request.method = "GET";
bncce36dca22015-04-21 22:11:2310457 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210458 request.load_flags = 0;
10459
[email protected]d973e99a2012-02-17 21:02:3610460 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210461 StaticSocketDataProvider first_data;
10462 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710463 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:4210464
10465 MockRead data_reads[] = {
10466 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10467 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610468 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210469 };
10470 StaticSocketDataProvider second_data(
10471 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710472 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210473
danakj1fd259a02016-04-16 03:17:0910474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210475
[email protected]30d4c022013-07-18 22:58:1610476 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310477 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610478 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110479 // Port must be < 1024, or the header will be ignored (since initial port was
10480 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010481 const AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810482 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bncd9b132e2015-07-08 05:16:1010483 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210484 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610485 http_server_properties->SetAlternativeService(server, alternative_service,
10486 expiration);
[email protected]564b4912010-03-09 16:30:4210487
danakj1fd259a02016-04-16 03:17:0910488 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010489 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110490 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210491
[email protected]49639fa2011-12-20 23:22:4110492 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:4210493 EXPECT_EQ(ERR_IO_PENDING, rv);
10494 EXPECT_EQ(OK, callback.WaitForResult());
10495
10496 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210497 ASSERT_TRUE(response);
10498 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210499 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10500
10501 std::string response_data;
10502 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10503 EXPECT_EQ("hello world", response_data);
10504
bncd9b132e2015-07-08 05:16:1010505 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610506 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010507 ASSERT_EQ(1u, alternative_service_vector.size());
10508 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10509 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10510 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210511}
10512
bnc55ff9da2015-08-19 18:42:3510513// Ensure that we are not allowed to redirect traffic via an alternate protocol
10514// to an unrestricted (port >= 1024) when the original traffic was on a
10515// restricted port (port < 1024). Ensure that we can redirect in all other
10516// cases.
[email protected]23e482282013-06-14 16:08:0210517TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310518 AlternateProtocolPortRestrictedBlocked) {
bncf33fb31b2016-01-29 15:22:2610519 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110520
10521 HttpRequestInfo restricted_port_request;
10522 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310523 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110524 restricted_port_request.load_flags = 0;
10525
[email protected]d973e99a2012-02-17 21:02:3610526 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110527 StaticSocketDataProvider first_data;
10528 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710529 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110530
10531 MockRead data_reads[] = {
10532 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10533 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610534 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110535 };
10536 StaticSocketDataProvider second_data(
10537 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710538 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110539
danakj1fd259a02016-04-16 03:17:0910540 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110541
[email protected]30d4c022013-07-18 22:58:1610542 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310543 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110544 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210545 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810546 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210547 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210548 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210549 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610550 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010551 expiration);
[email protected]3912662a32011-10-04 00:51:1110552
danakj1fd259a02016-04-16 03:17:0910553 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010554 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110555 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110556
[email protected]49639fa2011-12-20 23:22:4110557 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610558 &restricted_port_request,
10559 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110560 EXPECT_EQ(ERR_IO_PENDING, rv);
10561 // Invalid change to unrestricted port should fail.
10562 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:1910563}
[email protected]3912662a32011-10-04 00:51:1110564
bnc55ff9da2015-08-19 18:42:3510565// Ensure that we are allowed to redirect traffic via an alternate protocol to
10566// an unrestricted (port >= 1024) when the original traffic was on a restricted
10567// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:0210568TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:1910569 AlternateProtocolPortRestrictedPermitted) {
bncf33fb31b2016-01-29 15:22:2610570 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]bb88e1d32013-05-03 23:11:0710571 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910572
10573 HttpRequestInfo restricted_port_request;
10574 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310575 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910576 restricted_port_request.load_flags = 0;
10577
10578 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10579 StaticSocketDataProvider first_data;
10580 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710581 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910582
10583 MockRead data_reads[] = {
10584 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10585 MockRead("hello world"),
10586 MockRead(ASYNC, OK),
10587 };
10588 StaticSocketDataProvider second_data(
10589 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710590 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:1910591
danakj1fd259a02016-04-16 03:17:0910592 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910593
[email protected]30d4c022013-07-18 22:58:1610594 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910595 session->http_server_properties();
10596 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210597 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810598 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210599 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210600 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210601 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610602 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010603 expiration);
[email protected]c54c6962013-02-01 04:53:1910604
danakj1fd259a02016-04-16 03:17:0910605 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010606 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:1910607 TestCompletionCallback callback;
10608
10609 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:3610610 &restricted_port_request,
10611 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:1910612 // Change to unrestricted port should succeed.
10613 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110614}
10615
bnc55ff9da2015-08-19 18:42:3510616// Ensure that we are not allowed to redirect traffic via an alternate protocol
10617// to an unrestricted (port >= 1024) when the original traffic was on a
10618// restricted port (port < 1024). Ensure that we can redirect in all other
10619// cases.
[email protected]23e482282013-06-14 16:08:0210620TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310621 AlternateProtocolPortRestrictedAllowed) {
bncf33fb31b2016-01-29 15:22:2610622 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110623
10624 HttpRequestInfo restricted_port_request;
10625 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310626 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110627 restricted_port_request.load_flags = 0;
10628
[email protected]d973e99a2012-02-17 21:02:3610629 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110630 StaticSocketDataProvider first_data;
10631 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710632 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110633
10634 MockRead data_reads[] = {
10635 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10636 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610637 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110638 };
10639 StaticSocketDataProvider second_data(
10640 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710641 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110642
danakj1fd259a02016-04-16 03:17:0910643 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110644
[email protected]30d4c022013-07-18 22:58:1610645 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310646 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110647 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210648 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810649 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210650 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210651 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210652 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610653 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010654 expiration);
[email protected]3912662a32011-10-04 00:51:1110655
danakj1fd259a02016-04-16 03:17:0910656 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010657 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110658 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110659
[email protected]49639fa2011-12-20 23:22:4110660 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610661 &restricted_port_request,
10662 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110663 EXPECT_EQ(ERR_IO_PENDING, rv);
10664 // Valid change to restricted port should pass.
10665 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110666}
10667
bnc55ff9da2015-08-19 18:42:3510668// Ensure that we are not allowed to redirect traffic via an alternate protocol
10669// to an unrestricted (port >= 1024) when the original traffic was on a
10670// restricted port (port < 1024). Ensure that we can redirect in all other
10671// cases.
[email protected]23e482282013-06-14 16:08:0210672TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310673 AlternateProtocolPortUnrestrictedAllowed1) {
bncf33fb31b2016-01-29 15:22:2610674 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110675
10676 HttpRequestInfo unrestricted_port_request;
10677 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310678 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110679 unrestricted_port_request.load_flags = 0;
10680
[email protected]d973e99a2012-02-17 21:02:3610681 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110682 StaticSocketDataProvider first_data;
10683 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710684 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110685
10686 MockRead data_reads[] = {
10687 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10688 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610689 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110690 };
10691 StaticSocketDataProvider second_data(
10692 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710693 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110694
danakj1fd259a02016-04-16 03:17:0910695 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110696
[email protected]30d4c022013-07-18 22:58:1610697 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310698 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110699 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210700 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810701 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210702 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210703 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210704 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610705 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010706 expiration);
[email protected]3912662a32011-10-04 00:51:1110707
danakj1fd259a02016-04-16 03:17:0910708 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010709 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110710 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110711
[email protected]49639fa2011-12-20 23:22:4110712 int rv = trans->Start(
10713 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110714 EXPECT_EQ(ERR_IO_PENDING, rv);
10715 // Valid change to restricted port should pass.
10716 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110717}
10718
bnc55ff9da2015-08-19 18:42:3510719// Ensure that we are not allowed to redirect traffic via an alternate protocol
10720// to an unrestricted (port >= 1024) when the original traffic was on a
10721// restricted port (port < 1024). Ensure that we can redirect in all other
10722// cases.
[email protected]23e482282013-06-14 16:08:0210723TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310724 AlternateProtocolPortUnrestrictedAllowed2) {
bncf33fb31b2016-01-29 15:22:2610725 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110726
10727 HttpRequestInfo unrestricted_port_request;
10728 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310729 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110730 unrestricted_port_request.load_flags = 0;
10731
[email protected]d973e99a2012-02-17 21:02:3610732 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110733 StaticSocketDataProvider first_data;
10734 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710735 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110736
10737 MockRead data_reads[] = {
10738 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10739 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610740 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110741 };
10742 StaticSocketDataProvider second_data(
10743 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710744 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110745
danakj1fd259a02016-04-16 03:17:0910746 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110747
[email protected]30d4c022013-07-18 22:58:1610748 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310749 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210750 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:2210751 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810752 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210753 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210754 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210755 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610756 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010757 expiration);
[email protected]3912662a32011-10-04 00:51:1110758
danakj1fd259a02016-04-16 03:17:0910759 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010760 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110761 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110762
[email protected]49639fa2011-12-20 23:22:4110763 int rv = trans->Start(
10764 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110765 EXPECT_EQ(ERR_IO_PENDING, rv);
10766 // Valid change to an unrestricted port should pass.
10767 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110768}
10769
bnc55ff9da2015-08-19 18:42:3510770// Ensure that we are not allowed to redirect traffic via an alternate protocol
10771// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10772// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:2310773TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bncf33fb31b2016-01-29 15:22:2610774 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]eb6234e2012-01-19 01:50:0210775
10776 HttpRequestInfo request;
10777 request.method = "GET";
bncce36dca22015-04-21 22:11:2310778 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210779 request.load_flags = 0;
10780
10781 // The alternate protocol request will error out before we attempt to connect,
10782 // so only the standard HTTP request will try to connect.
10783 MockRead data_reads[] = {
10784 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10785 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610786 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210787 };
10788 StaticSocketDataProvider data(
10789 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710790 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210791
danakj1fd259a02016-04-16 03:17:0910792 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210793
[email protected]30d4c022013-07-18 22:58:1610794 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210795 session->http_server_properties();
10796 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:2210797 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810798 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210799 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210800 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210801 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610802 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210803
danakj1fd259a02016-04-16 03:17:0910804 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010805 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:0210806 TestCompletionCallback callback;
10807
10808 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10809 EXPECT_EQ(ERR_IO_PENDING, rv);
10810 // The HTTP request should succeed.
10811 EXPECT_EQ(OK, callback.WaitForResult());
10812
[email protected]eb6234e2012-01-19 01:50:0210813 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210814 ASSERT_TRUE(response);
10815 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210816 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10817
10818 std::string response_data;
10819 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10820 EXPECT_EQ("hello world", response_data);
10821}
10822
[email protected]23e482282013-06-14 16:08:0210823TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc1c196c6e2016-05-28 13:51:4810824 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2ff8b312010-04-26 22:20:5410825
10826 HttpRequestInfo request;
10827 request.method = "GET";
bncce36dca22015-04-21 22:11:2310828 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410829 request.load_flags = 0;
10830
bnc1c196c6e2016-05-28 13:51:4810831 std::string alternative_service_http_header =
10832 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310833
[email protected]2ff8b312010-04-26 22:20:5410834 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210835 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810836 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210837 MockRead("\r\n"),
10838 MockRead("hello world"),
10839 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10840 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410841
10842 StaticSocketDataProvider first_transaction(
10843 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710844 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410845
[email protected]8ddf8322012-02-23 18:08:0610846 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810847 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310848 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10849 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710850 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410851
danakj1fd259a02016-04-16 03:17:0910852 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4910853 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310854 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410855
danakj1fd259a02016-04-16 03:17:0910856 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5510857 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910858 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5510859 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410860 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310861 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410862 };
10863
rch8e6c6c42015-05-01 14:05:1310864 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10865 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710866 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410867
[email protected]d973e99a2012-02-17 21:02:3610868 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510869 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10870 NULL, 0, NULL, 0);
10871 hanging_non_alternate_protocol_socket.set_connect_data(
10872 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710873 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510874 &hanging_non_alternate_protocol_socket);
10875
[email protected]49639fa2011-12-20 23:22:4110876 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410877
danakj1fd259a02016-04-16 03:17:0910878 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10879 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010880 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410881
[email protected]49639fa2011-12-20 23:22:4110882 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410883 EXPECT_EQ(ERR_IO_PENDING, rv);
10884 EXPECT_EQ(OK, callback.WaitForResult());
10885
10886 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210887 ASSERT_TRUE(response);
10888 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410889 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10890
10891 std::string response_data;
10892 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10893 EXPECT_EQ("hello world", response_data);
10894
[email protected]90499482013-06-01 00:39:5010895 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410896
[email protected]49639fa2011-12-20 23:22:4110897 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410898 EXPECT_EQ(ERR_IO_PENDING, rv);
10899 EXPECT_EQ(OK, callback.WaitForResult());
10900
10901 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210902 ASSERT_TRUE(response);
10903 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210904 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310905 EXPECT_TRUE(response->was_fetched_via_spdy);
10906 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410907
10908 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10909 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410910}
10911
[email protected]23e482282013-06-14 16:08:0210912TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc1c196c6e2016-05-28 13:51:4810913 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2d6728692011-03-12 01:39:5510914
10915 HttpRequestInfo request;
10916 request.method = "GET";
bncce36dca22015-04-21 22:11:2310917 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510918 request.load_flags = 0;
10919
bnc1c196c6e2016-05-28 13:51:4810920 std::string alternative_service_http_header =
10921 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310922
[email protected]2d6728692011-03-12 01:39:5510923 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210924 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810925 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210926 MockRead("\r\n"),
10927 MockRead("hello world"),
10928 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10929 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510930 };
10931
10932 StaticSocketDataProvider first_transaction(
10933 data_reads, arraysize(data_reads), NULL, 0);
10934 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:0710935 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510936
[email protected]d973e99a2012-02-17 21:02:3610937 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810938 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10939 hanging_socket1.set_connect_data(never_finishing_connect);
[email protected]2d6728692011-03-12 01:39:5510940 // Socket 2 and 3 are the hanging Alternate-Protocol and
10941 // non-Alternate-Protocol jobs from the 2nd transaction.
mmenkecc2298e2015-12-07 18:20:1810942 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10943
10944 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10945 hanging_socket2.set_connect_data(never_finishing_connect);
10946 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510947
[email protected]8ddf8322012-02-23 18:08:0610948 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810949 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310950 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5210951 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0710952 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510953
danakj1fd259a02016-04-16 03:17:0910954 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4910955 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
danakj1fd259a02016-04-16 03:17:0910956 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4910957 spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:5510958 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310959 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:5510960 };
danakj1fd259a02016-04-16 03:17:0910961 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5510962 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910963 std::unique_ptr<SpdySerializedFrame> data1(
bncb03b1092016-04-06 11:19:5510964 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0910965 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5510966 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0910967 std::unique_ptr<SpdySerializedFrame> data2(
bncb03b1092016-04-06 11:19:5510968 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510969 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310970 CreateMockRead(*resp1, 2),
10971 CreateMockRead(*data1, 3),
10972 CreateMockRead(*resp2, 4),
10973 CreateMockRead(*data2, 5),
10974 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510975 };
10976
rch8e6c6c42015-05-01 14:05:1310977 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10978 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:5510979 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710980 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510981
10982 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
mmenkecc2298e2015-12-07 18:20:1810983 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10984 hanging_socket3.set_connect_data(never_finishing_connect);
10985 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510986
danakj1fd259a02016-04-16 03:17:0910987 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110988 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010989 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510990
[email protected]49639fa2011-12-20 23:22:4110991 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510992 EXPECT_EQ(ERR_IO_PENDING, rv);
10993 EXPECT_EQ(OK, callback1.WaitForResult());
10994
10995 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5210996 ASSERT_TRUE(response);
10997 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5510998 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10999
11000 std::string response_data;
11001 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11002 EXPECT_EQ("hello world", response_data);
11003
[email protected]49639fa2011-12-20 23:22:4111004 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011005 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111006 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511007 EXPECT_EQ(ERR_IO_PENDING, rv);
11008
[email protected]49639fa2011-12-20 23:22:4111009 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011010 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111011 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511012 EXPECT_EQ(ERR_IO_PENDING, rv);
11013
11014 EXPECT_EQ(OK, callback2.WaitForResult());
11015 EXPECT_EQ(OK, callback3.WaitForResult());
11016
11017 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211018 ASSERT_TRUE(response);
11019 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211020 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511021 EXPECT_TRUE(response->was_fetched_via_spdy);
11022 EXPECT_TRUE(response->was_npn_negotiated);
11023 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11024 EXPECT_EQ("hello!", response_data);
11025
11026 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211027 ASSERT_TRUE(response);
11028 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211029 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511030 EXPECT_TRUE(response->was_fetched_via_spdy);
11031 EXPECT_TRUE(response->was_npn_negotiated);
11032 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
11033 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511034}
11035
bnc1c196c6e2016-05-28 13:51:4811036TEST_P(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
11037 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2d6728692011-03-12 01:39:5511038
11039 HttpRequestInfo request;
11040 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2511041 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511042 request.load_flags = 0;
11043
bnc1c196c6e2016-05-28 13:51:4811044 std::string alternative_service_http_header =
11045 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4311046
[email protected]2d6728692011-03-12 01:39:5511047 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211048 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4811049 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5211050 MockRead("\r\n"),
11051 MockRead("hello world"),
11052 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11053 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511054 };
11055
11056 StaticSocketDataProvider first_transaction(
11057 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711058 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511059
[email protected]8ddf8322012-02-23 18:08:0611060 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811061 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0711062 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511063
[email protected]d973e99a2012-02-17 21:02:3611064 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511065 StaticSocketDataProvider hanging_alternate_protocol_socket(
11066 NULL, 0, NULL, 0);
11067 hanging_alternate_protocol_socket.set_connect_data(
11068 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711069 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511070 &hanging_alternate_protocol_socket);
11071
11072 // 2nd request is just a copy of the first one, over HTTP again.
mmenkecc2298e2015-12-07 18:20:1811073 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11074 NULL, 0);
11075 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
[email protected]2d6728692011-03-12 01:39:5511076
[email protected]49639fa2011-12-20 23:22:4111077 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511078
danakj1fd259a02016-04-16 03:17:0911079 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11080 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011081 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511082
[email protected]49639fa2011-12-20 23:22:4111083 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511084 EXPECT_EQ(ERR_IO_PENDING, rv);
11085 EXPECT_EQ(OK, callback.WaitForResult());
11086
11087 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211088 ASSERT_TRUE(response);
11089 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511090 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11091
11092 std::string response_data;
11093 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11094 EXPECT_EQ("hello world", response_data);
11095
[email protected]90499482013-06-01 00:39:5011096 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511097
[email protected]49639fa2011-12-20 23:22:4111098 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511099 EXPECT_EQ(ERR_IO_PENDING, rv);
11100 EXPECT_EQ(OK, callback.WaitForResult());
11101
11102 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211103 ASSERT_TRUE(response);
11104 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511105 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11106 EXPECT_FALSE(response->was_fetched_via_spdy);
11107 EXPECT_FALSE(response->was_npn_negotiated);
11108
11109 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11110 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511111}
11112
[email protected]631f1322010-04-30 17:59:1111113class CapturingProxyResolver : public ProxyResolver {
11114 public:
sammce90c9212015-05-27 23:43:3511115 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011116 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111117
dchengb03027d2014-10-21 12:00:2011118 int GetProxyForURL(const GURL& url,
11119 ProxyInfo* results,
11120 const CompletionCallback& callback,
eroman9c8f4242016-02-29 21:16:5411121 RequestHandle* request,
dchengb03027d2014-10-21 12:00:2011122 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011123 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11124 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211125 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111126 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211127 return OK;
[email protected]631f1322010-04-30 17:59:1111128 }
11129
eroman9c8f4242016-02-29 21:16:5411130 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
11131
11132 LoadState GetLoadState(RequestHandle request) const override {
11133 NOTREACHED();
11134 return LOAD_STATE_IDLE;
11135 }
11136
[email protected]24476402010-07-20 20:55:1711137 const std::vector<GURL>& resolved() const { return resolved_; }
11138
11139 private:
[email protected]631f1322010-04-30 17:59:1111140 std::vector<GURL> resolved_;
11141
11142 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11143};
11144
sammce64b2362015-04-29 03:50:2311145class CapturingProxyResolverFactory : public ProxyResolverFactory {
11146 public:
11147 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11148 : ProxyResolverFactory(false), resolver_(resolver) {}
11149
11150 int CreateProxyResolver(
11151 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911152 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311153 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911154 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2311155 resolver->reset(new ForwardingProxyResolver(resolver_));
11156 return OK;
11157 }
11158
11159 private:
11160 ProxyResolver* resolver_;
11161};
11162
bnc1c196c6e2016-05-28 13:51:4811163TEST_P(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
11164 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]631f1322010-04-30 17:59:1111165
11166 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211167 proxy_config.set_auto_detect(true);
11168 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111169
sammc5dd160c2015-04-02 02:43:1311170 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711171 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0911172 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)),
11173 base::WrapUnique(
sammce64b2362015-04-29 03:50:2311174 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:3811175 NULL));
vishal.b62985ca92015-04-17 08:45:5111176 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711177 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111178
11179 HttpRequestInfo request;
11180 request.method = "GET";
bncce36dca22015-04-21 22:11:2311181 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111182 request.load_flags = 0;
11183
bnc1c196c6e2016-05-28 13:51:4811184 std::string alternative_service_http_header =
11185 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4311186
[email protected]631f1322010-04-30 17:59:1111187 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211188 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4811189 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5211190 MockRead("\r\n"),
11191 MockRead("hello world"),
11192 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11193 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111194 };
11195
11196 StaticSocketDataProvider first_transaction(
11197 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711198 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1111199
[email protected]8ddf8322012-02-23 18:08:0611200 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811201 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2311202 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5211203 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0711204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1111205
danakj1fd259a02016-04-16 03:17:0911206 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911207 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1111208 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311209 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511210 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11211 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311212 "Proxy-Connection: keep-alive\r\n\r\n"),
11213 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1111214 };
11215
[email protected]d911f1b2010-05-05 22:39:4211216 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11217
danakj1fd259a02016-04-16 03:17:0911218 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5511219 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0911220 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5511221 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111222 MockRead spdy_reads[] = {
mmenkee24011922015-12-17 22:12:5911223 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(*resp.get(), 3),
11224 CreateMockRead(*data.get(), 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111225 };
11226
rch8e6c6c42015-05-01 14:05:1311227 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11228 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711229 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111230
[email protected]d973e99a2012-02-17 21:02:3611231 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511232 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11233 NULL, 0, NULL, 0);
11234 hanging_non_alternate_protocol_socket.set_connect_data(
11235 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711236 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511237 &hanging_non_alternate_protocol_socket);
11238
[email protected]49639fa2011-12-20 23:22:4111239 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111240
danakj1fd259a02016-04-16 03:17:0911241 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11242 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011243 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111244
[email protected]49639fa2011-12-20 23:22:4111245 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1111246 EXPECT_EQ(ERR_IO_PENDING, rv);
11247 EXPECT_EQ(OK, callback.WaitForResult());
11248
11249 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211250 ASSERT_TRUE(response);
11251 ASSERT_TRUE(response->headers);
[email protected]631f1322010-04-30 17:59:1111252 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311253 EXPECT_FALSE(response->was_fetched_via_spdy);
11254 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1111255
11256 std::string response_data;
11257 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11258 EXPECT_EQ("hello world", response_data);
11259
[email protected]90499482013-06-01 00:39:5011260 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111261
[email protected]49639fa2011-12-20 23:22:4111262 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1111263 EXPECT_EQ(ERR_IO_PENDING, rv);
11264 EXPECT_EQ(OK, callback.WaitForResult());
11265
11266 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211267 ASSERT_TRUE(response);
11268 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211269 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311270 EXPECT_TRUE(response->was_fetched_via_spdy);
11271 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1111272
11273 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11274 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1311275 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2311276 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311277 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311278 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311279 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111280
[email protected]029c83b62013-01-24 05:28:2011281 LoadTimingInfo load_timing_info;
11282 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11283 TestLoadTimingNotReusedWithPac(load_timing_info,
11284 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111285}
[email protected]631f1322010-04-30 17:59:1111286
[email protected]23e482282013-06-14 16:08:0211287TEST_P(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811288 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
11289 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2ff8b312010-04-26 22:20:5411290
11291 HttpRequestInfo request;
11292 request.method = "GET";
bncce36dca22015-04-21 22:11:2311293 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411294 request.load_flags = 0;
11295
bnc1c196c6e2016-05-28 13:51:4811296 std::string alternative_service_http_header =
11297 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4311298
[email protected]2ff8b312010-04-26 22:20:5411299 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211300 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4811301 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5211302 MockRead("\r\n"),
11303 MockRead("hello world"),
11304 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411305 };
11306
11307 StaticSocketDataProvider first_transaction(
11308 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711309 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5411310
[email protected]8ddf8322012-02-23 18:08:0611311 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811312 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2311313 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5211314 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0711315 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5411316
danakj1fd259a02016-04-16 03:17:0911317 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911318 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1311319 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411320
danakj1fd259a02016-04-16 03:17:0911321 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5511322 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0911323 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5511324 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411325 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311326 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411327 };
11328
rch8e6c6c42015-05-01 14:05:1311329 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11330 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711331 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411332
[email protected]83039bb2011-12-09 18:43:5511333 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411334
danakj1fd259a02016-04-16 03:17:0911335 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411336
danakj1fd259a02016-04-16 03:17:0911337 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011338 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411339
[email protected]49639fa2011-12-20 23:22:4111340 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5411341 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111342 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5411343
11344 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211345 ASSERT_TRUE(response);
11346 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411347 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11348
11349 std::string response_data;
11350 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11351 EXPECT_EQ("hello world", response_data);
11352
11353 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511354 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011355 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311356 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711357 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4211358 CreateSecureSpdySession(session.get(), key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3811359
[email protected]90499482013-06-01 00:39:5011360 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411361
[email protected]49639fa2011-12-20 23:22:4111362 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5411363 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111364 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5411365
11366 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211367 ASSERT_TRUE(response);
11368 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211369 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311370 EXPECT_TRUE(response->was_fetched_via_spdy);
11371 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411372
11373 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11374 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211375}
11376
[email protected]044de0642010-06-17 10:42:1511377// GenerateAuthToken is a mighty big test.
11378// It tests all permutation of GenerateAuthToken behavior:
11379// - Synchronous and Asynchronous completion.
11380// - OK or error on completion.
11381// - Direct connection, non-authenticating proxy, and authenticating proxy.
11382// - HTTP or HTTPS backend (to include proxy tunneling).
11383// - Non-authenticating and authenticating backend.
11384//
[email protected]fe3b7dc2012-02-03 19:52:0911385// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511386// problems generating an auth token for an authenticating proxy, we don't
11387// need to test all permutations of the backend server).
11388//
11389// The test proceeds by going over each of the configuration cases, and
11390// potentially running up to three rounds in each of the tests. The TestConfig
11391// specifies both the configuration for the test as well as the expectations
11392// for the results.
[email protected]23e482282013-06-14 16:08:0211393TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011394 static const char kServer[] = "http://www.example.com";
11395 static const char kSecureServer[] = "https://www.example.com";
11396 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511397 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
11398
11399 enum AuthTiming {
11400 AUTH_NONE,
11401 AUTH_SYNC,
11402 AUTH_ASYNC,
11403 };
11404
11405 const MockWrite kGet(
11406 "GET / HTTP/1.1\r\n"
11407 "Host: www.example.com\r\n"
11408 "Connection: keep-alive\r\n\r\n");
11409 const MockWrite kGetProxy(
11410 "GET http://www.example.com/ HTTP/1.1\r\n"
11411 "Host: www.example.com\r\n"
11412 "Proxy-Connection: keep-alive\r\n\r\n");
11413 const MockWrite kGetAuth(
11414 "GET / HTTP/1.1\r\n"
11415 "Host: www.example.com\r\n"
11416 "Connection: keep-alive\r\n"
11417 "Authorization: auth_token\r\n\r\n");
11418 const MockWrite kGetProxyAuth(
11419 "GET http://www.example.com/ HTTP/1.1\r\n"
11420 "Host: www.example.com\r\n"
11421 "Proxy-Connection: keep-alive\r\n"
11422 "Proxy-Authorization: auth_token\r\n\r\n");
11423 const MockWrite kGetAuthThroughProxy(
11424 "GET http://www.example.com/ HTTP/1.1\r\n"
11425 "Host: www.example.com\r\n"
11426 "Proxy-Connection: keep-alive\r\n"
11427 "Authorization: auth_token\r\n\r\n");
11428 const MockWrite kGetAuthWithProxyAuth(
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"
11433 "Authorization: auth_token\r\n\r\n");
11434 const MockWrite kConnect(
11435 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711436 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511437 "Proxy-Connection: keep-alive\r\n\r\n");
11438 const MockWrite kConnectProxyAuth(
11439 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711440 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511441 "Proxy-Connection: keep-alive\r\n"
11442 "Proxy-Authorization: auth_token\r\n\r\n");
11443
11444 const MockRead kSuccess(
11445 "HTTP/1.1 200 OK\r\n"
11446 "Content-Type: text/html; charset=iso-8859-1\r\n"
11447 "Content-Length: 3\r\n\r\n"
11448 "Yes");
11449 const MockRead kFailure(
11450 "Should not be called.");
11451 const MockRead kServerChallenge(
11452 "HTTP/1.1 401 Unauthorized\r\n"
11453 "WWW-Authenticate: Mock realm=server\r\n"
11454 "Content-Type: text/html; charset=iso-8859-1\r\n"
11455 "Content-Length: 14\r\n\r\n"
11456 "Unauthorized\r\n");
11457 const MockRead kProxyChallenge(
11458 "HTTP/1.1 407 Unauthorized\r\n"
11459 "Proxy-Authenticate: Mock realm=proxy\r\n"
11460 "Proxy-Connection: close\r\n"
11461 "Content-Type: text/html; charset=iso-8859-1\r\n"
11462 "Content-Length: 14\r\n\r\n"
11463 "Unauthorized\r\n");
11464 const MockRead kProxyConnected(
11465 "HTTP/1.1 200 Connection Established\r\n\r\n");
11466
11467 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11468 // no constructors, but the C++ compiler on Windows warns about
11469 // unspecified data in compound literals. So, moved to using constructors,
11470 // and TestRound's created with the default constructor should not be used.
11471 struct TestRound {
11472 TestRound()
11473 : expected_rv(ERR_UNEXPECTED),
11474 extra_write(NULL),
11475 extra_read(NULL) {
11476 }
11477 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11478 int expected_rv_arg)
11479 : write(write_arg),
11480 read(read_arg),
11481 expected_rv(expected_rv_arg),
11482 extra_write(NULL),
11483 extra_read(NULL) {
11484 }
11485 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11486 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111487 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511488 : write(write_arg),
11489 read(read_arg),
11490 expected_rv(expected_rv_arg),
11491 extra_write(extra_write_arg),
11492 extra_read(extra_read_arg) {
11493 }
11494 MockWrite write;
11495 MockRead read;
11496 int expected_rv;
11497 const MockWrite* extra_write;
11498 const MockRead* extra_read;
11499 };
11500
11501 static const int kNoSSL = 500;
11502
11503 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5111504 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511505 AuthTiming proxy_auth_timing;
11506 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5111507 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511508 AuthTiming server_auth_timing;
11509 int server_auth_rv;
11510 int num_auth_rounds;
11511 int first_ssl_round;
11512 TestRound rounds[3];
11513 } test_configs[] = {
11514 // Non-authenticating HTTP server with a direct connection.
11515 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11516 { TestRound(kGet, kSuccess, OK)}},
11517 // Authenticating HTTP server with a direct connection.
11518 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11519 { TestRound(kGet, kServerChallenge, OK),
11520 TestRound(kGetAuth, kSuccess, OK)}},
11521 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11522 { TestRound(kGet, kServerChallenge, OK),
11523 TestRound(kGetAuth, kFailure, kAuthErr)}},
11524 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11525 { TestRound(kGet, kServerChallenge, OK),
11526 TestRound(kGetAuth, kSuccess, OK)}},
11527 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11528 { TestRound(kGet, kServerChallenge, OK),
11529 TestRound(kGetAuth, kFailure, kAuthErr)}},
11530 // Non-authenticating HTTP server through a non-authenticating proxy.
11531 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11532 { TestRound(kGetProxy, kSuccess, OK)}},
11533 // Authenticating HTTP server through a non-authenticating proxy.
11534 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11535 { TestRound(kGetProxy, kServerChallenge, OK),
11536 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11537 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11538 { TestRound(kGetProxy, kServerChallenge, OK),
11539 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11540 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11541 { TestRound(kGetProxy, kServerChallenge, OK),
11542 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11543 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11544 { TestRound(kGetProxy, kServerChallenge, OK),
11545 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11546 // Non-authenticating HTTP server through an authenticating proxy.
11547 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11548 { TestRound(kGetProxy, kProxyChallenge, OK),
11549 TestRound(kGetProxyAuth, kSuccess, OK)}},
11550 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11551 { TestRound(kGetProxy, kProxyChallenge, OK),
11552 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11553 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11554 { TestRound(kGetProxy, kProxyChallenge, OK),
11555 TestRound(kGetProxyAuth, kSuccess, OK)}},
11556 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11557 { TestRound(kGetProxy, kProxyChallenge, OK),
11558 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11559 // Authenticating HTTP server through an authenticating proxy.
11560 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11561 { TestRound(kGetProxy, kProxyChallenge, OK),
11562 TestRound(kGetProxyAuth, kServerChallenge, OK),
11563 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11564 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11565 { TestRound(kGetProxy, kProxyChallenge, OK),
11566 TestRound(kGetProxyAuth, kServerChallenge, OK),
11567 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11568 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11569 { TestRound(kGetProxy, kProxyChallenge, OK),
11570 TestRound(kGetProxyAuth, kServerChallenge, OK),
11571 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11572 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11573 { TestRound(kGetProxy, kProxyChallenge, OK),
11574 TestRound(kGetProxyAuth, kServerChallenge, OK),
11575 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11576 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11577 { TestRound(kGetProxy, kProxyChallenge, OK),
11578 TestRound(kGetProxyAuth, kServerChallenge, OK),
11579 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11580 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11581 { TestRound(kGetProxy, kProxyChallenge, OK),
11582 TestRound(kGetProxyAuth, kServerChallenge, OK),
11583 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11584 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11585 { TestRound(kGetProxy, kProxyChallenge, OK),
11586 TestRound(kGetProxyAuth, kServerChallenge, OK),
11587 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11588 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11589 { TestRound(kGetProxy, kProxyChallenge, OK),
11590 TestRound(kGetProxyAuth, kServerChallenge, OK),
11591 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11592 // Non-authenticating HTTPS server with a direct connection.
11593 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11594 { TestRound(kGet, kSuccess, OK)}},
11595 // Authenticating HTTPS server with a direct connection.
11596 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11597 { TestRound(kGet, kServerChallenge, OK),
11598 TestRound(kGetAuth, kSuccess, OK)}},
11599 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11600 { TestRound(kGet, kServerChallenge, OK),
11601 TestRound(kGetAuth, kFailure, kAuthErr)}},
11602 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11603 { TestRound(kGet, kServerChallenge, OK),
11604 TestRound(kGetAuth, kSuccess, OK)}},
11605 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11606 { TestRound(kGet, kServerChallenge, OK),
11607 TestRound(kGetAuth, kFailure, kAuthErr)}},
11608 // Non-authenticating HTTPS server with a non-authenticating proxy.
11609 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11610 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11611 // Authenticating HTTPS server through a non-authenticating proxy.
11612 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11613 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11614 TestRound(kGetAuth, kSuccess, OK)}},
11615 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11616 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11617 TestRound(kGetAuth, kFailure, kAuthErr)}},
11618 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11619 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11620 TestRound(kGetAuth, kSuccess, OK)}},
11621 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11622 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11623 TestRound(kGetAuth, kFailure, kAuthErr)}},
11624 // Non-Authenticating HTTPS server through an authenticating proxy.
11625 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11626 { TestRound(kConnect, kProxyChallenge, OK),
11627 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11628 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11629 { TestRound(kConnect, kProxyChallenge, OK),
11630 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11631 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11632 { TestRound(kConnect, kProxyChallenge, OK),
11633 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11634 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11635 { TestRound(kConnect, kProxyChallenge, OK),
11636 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11637 // Authenticating HTTPS server through an authenticating proxy.
11638 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11639 { TestRound(kConnect, kProxyChallenge, OK),
11640 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11641 &kGet, &kServerChallenge),
11642 TestRound(kGetAuth, kSuccess, OK)}},
11643 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11644 { TestRound(kConnect, kProxyChallenge, OK),
11645 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11646 &kGet, &kServerChallenge),
11647 TestRound(kGetAuth, kFailure, kAuthErr)}},
11648 { kProxy, AUTH_ASYNC, 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_ASYNC, 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_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11659 { TestRound(kConnect, kProxyChallenge, OK),
11660 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11661 &kGet, &kServerChallenge),
11662 TestRound(kGetAuth, kSuccess, OK)}},
11663 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11664 { TestRound(kConnect, kProxyChallenge, OK),
11665 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11666 &kGet, &kServerChallenge),
11667 TestRound(kGetAuth, kFailure, kAuthErr)}},
11668 { kProxy, AUTH_ASYNC, 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_ASYNC, 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 };
11679
viettrungluue4a8b882014-10-16 06:17:3811680 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0811681 HttpAuthHandlerMock::Factory* auth_factory(
11682 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711683 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4911684 SSLInfo empty_ssl_info;
[email protected]044de0642010-06-17 10:42:1511685 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2611686
11687 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1511688 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0811689 for (int n = 0; n < 2; n++) {
11690 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11691 std::string auth_challenge = "Mock realm=proxy";
11692 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2411693 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11694 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0811695 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
asanka5ffd5d72016-03-23 16:20:4911696 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811697 auth_handler->SetGenerateExpectation(
11698 test_config.proxy_auth_timing == AUTH_ASYNC,
11699 test_config.proxy_auth_rv);
11700 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11701 }
[email protected]044de0642010-06-17 10:42:1511702 }
11703 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0011704 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1511705 std::string auth_challenge = "Mock realm=server";
11706 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2411707 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11708 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1511709 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911710 empty_ssl_info, origin, BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511711 auth_handler->SetGenerateExpectation(
11712 test_config.server_auth_timing == AUTH_ASYNC,
11713 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0811714 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1511715 }
11716 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0311717 session_deps_.proxy_service =
11718 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1511719 } else {
rdsmith82957ad2015-09-16 19:42:0311720 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1511721 }
11722
11723 HttpRequestInfo request;
11724 request.method = "GET";
11725 request.url = GURL(test_config.server_url);
11726 request.load_flags = 0;
11727
danakj1fd259a02016-04-16 03:17:0911728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1511729
rchcb68dc62015-05-21 04:45:3611730 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
11731
11732 std::vector<std::vector<MockRead>> mock_reads(1);
11733 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1511734 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11735 const TestRound& read_write_round = test_config.rounds[round];
11736
11737 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3611738 mock_reads.back().push_back(read_write_round.read);
11739 mock_writes.back().push_back(read_write_round.write);
11740
11741 // kProxyChallenge uses Proxy-Connection: close which means that the
11742 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5411743 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3611744 mock_reads.push_back(std::vector<MockRead>());
11745 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1511746 }
11747
rchcb68dc62015-05-21 04:45:3611748 if (read_write_round.extra_read) {
11749 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1511750 }
rchcb68dc62015-05-21 04:45:3611751 if (read_write_round.extra_write) {
11752 mock_writes.back().push_back(*read_write_round.extra_write);
11753 }
[email protected]044de0642010-06-17 10:42:1511754
11755 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1511756 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0711757 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1511758 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3611759 }
[email protected]044de0642010-06-17 10:42:1511760
danakj1fd259a02016-04-16 03:17:0911761 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3611762 for (size_t i = 0; i < mock_reads.size(); ++i) {
danakj1fd259a02016-04-16 03:17:0911763 data_providers.push_back(base::WrapUnique(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5411764 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3211765 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3611766 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3211767 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3611768 }
11769
mmenkecc2298e2015-12-07 18:20:1811770 // Transaction must be created after DataProviders, so it's destroyed before
11771 // they are as well.
11772 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11773
rchcb68dc62015-05-21 04:45:3611774 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11775 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1511776 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4111777 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1511778 int rv;
11779 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4111780 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511781 } else {
[email protected]49639fa2011-12-20 23:22:4111782 rv = trans.RestartWithAuth(
11783 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1511784 }
11785 if (rv == ERR_IO_PENDING)
11786 rv = callback.WaitForResult();
11787
11788 // Compare results with expected data.
11789 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5011790 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5511791 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1511792 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
11793 continue;
11794 }
11795 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5211796 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511797 } else {
wezca1070932016-05-26 20:30:5211798 EXPECT_FALSE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511799 }
11800 }
[email protected]e5ae96a2010-04-14 20:12:4511801 }
11802}
11803
[email protected]23e482282013-06-14 16:08:0211804TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1411805 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1411806 HttpAuthHandlerMock::Factory* auth_factory(
11807 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711808 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0311809 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0711810 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
11811 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1411812
11813 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11814 auth_handler->set_connection_based(true);
11815 std::string auth_challenge = "Mock realm=server";
11816 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2411817 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11818 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4911819 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1411820 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911821 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811822 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1411823
[email protected]c871bce92010-07-15 21:51:1411824 int rv = OK;
11825 const HttpResponseInfo* response = NULL;
11826 HttpRequestInfo request;
11827 request.method = "GET";
11828 request.url = origin;
11829 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2711830
danakj1fd259a02016-04-16 03:17:0911831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1011832
11833 // Use a TCP Socket Pool with only one connection per group. This is used
11834 // to validate that the TCP socket is not released to the pool between
11835 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4211836 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2811837 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1011838 50, // Max sockets for pool
11839 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2111840 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
11841 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0911842 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4411843 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0211844 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4811845 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1011846
danakj1fd259a02016-04-16 03:17:0911847 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011848 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111849 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1411850
11851 const MockWrite kGet(
11852 "GET / HTTP/1.1\r\n"
11853 "Host: www.example.com\r\n"
11854 "Connection: keep-alive\r\n\r\n");
11855 const MockWrite kGetAuth(
11856 "GET / HTTP/1.1\r\n"
11857 "Host: www.example.com\r\n"
11858 "Connection: keep-alive\r\n"
11859 "Authorization: auth_token\r\n\r\n");
11860
11861 const MockRead kServerChallenge(
11862 "HTTP/1.1 401 Unauthorized\r\n"
11863 "WWW-Authenticate: Mock realm=server\r\n"
11864 "Content-Type: text/html; charset=iso-8859-1\r\n"
11865 "Content-Length: 14\r\n\r\n"
11866 "Unauthorized\r\n");
11867 const MockRead kSuccess(
11868 "HTTP/1.1 200 OK\r\n"
11869 "Content-Type: text/html; charset=iso-8859-1\r\n"
11870 "Content-Length: 3\r\n\r\n"
11871 "Yes");
11872
11873 MockWrite writes[] = {
11874 // First round
11875 kGet,
11876 // Second round
11877 kGetAuth,
11878 // Third round
11879 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3011880 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1011881 kGetAuth,
11882 // Competing request
11883 kGet,
[email protected]c871bce92010-07-15 21:51:1411884 };
11885 MockRead reads[] = {
11886 // First round
11887 kServerChallenge,
11888 // Second round
11889 kServerChallenge,
11890 // Third round
[email protected]eca50e122010-09-11 14:03:3011891 kServerChallenge,
11892 // Fourth round
[email protected]c871bce92010-07-15 21:51:1411893 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1011894 // Competing response
11895 kSuccess,
[email protected]c871bce92010-07-15 21:51:1411896 };
11897 StaticSocketDataProvider data_provider(reads, arraysize(reads),
11898 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0711899 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1411900
thestig9d3bb0c2015-01-24 00:49:5111901 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1011902
11903 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1411904 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111905 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1411906 if (rv == ERR_IO_PENDING)
11907 rv = callback.WaitForResult();
11908 EXPECT_EQ(OK, rv);
11909 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211910 ASSERT_TRUE(response);
11911 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811912 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411913
[email protected]7ef4cbbb2011-02-06 11:19:1011914 // In between rounds, another request comes in for the same domain.
11915 // It should not be able to grab the TCP socket that trans has already
11916 // claimed.
danakj1fd259a02016-04-16 03:17:0911917 std::unique_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5011918 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111919 TestCompletionCallback callback_compete;
11920 rv = trans_compete->Start(
11921 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1011922 EXPECT_EQ(ERR_IO_PENDING, rv);
11923 // callback_compete.WaitForResult at this point would stall forever,
11924 // since the HttpNetworkTransaction does not release the request back to
11925 // the pool until after authentication completes.
11926
11927 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1411928 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111929 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411930 if (rv == ERR_IO_PENDING)
11931 rv = callback.WaitForResult();
11932 EXPECT_EQ(OK, rv);
11933 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211934 ASSERT_TRUE(response);
11935 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811936 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411937
[email protected]7ef4cbbb2011-02-06 11:19:1011938 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1411939 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111940 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411941 if (rv == ERR_IO_PENDING)
11942 rv = callback.WaitForResult();
11943 EXPECT_EQ(OK, rv);
11944 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211945 ASSERT_TRUE(response);
11946 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811947 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3011948
[email protected]7ef4cbbb2011-02-06 11:19:1011949 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3011950 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111951 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3011952 if (rv == ERR_IO_PENDING)
11953 rv = callback.WaitForResult();
11954 EXPECT_EQ(OK, rv);
11955 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211956 ASSERT_TRUE(response);
11957 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811958 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011959
11960 // Read the body since the fourth round was successful. This will also
11961 // release the socket back to the pool.
11962 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5011963 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011964 if (rv == ERR_IO_PENDING)
11965 rv = callback.WaitForResult();
11966 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011967 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011968 EXPECT_EQ(0, rv);
11969 // There are still 0 idle sockets, since the trans_compete transaction
11970 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2811971 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011972
11973 // The competing request can now finish. Wait for the headers and then
11974 // read the body.
11975 rv = callback_compete.WaitForResult();
11976 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5011977 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011978 if (rv == ERR_IO_PENDING)
11979 rv = callback.WaitForResult();
11980 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011981 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011982 EXPECT_EQ(0, rv);
11983
11984 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2811985 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411986}
11987
[email protected]65041fa2010-05-21 06:56:5311988// This tests the case that a request is issued via http instead of spdy after
11989// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0211990TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bncf33fb31b2016-01-29 15:22:2611991 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d7599122014-05-24 03:37:2311992
[email protected]65041fa2010-05-21 06:56:5311993 HttpRequestInfo request;
11994 request.method = "GET";
bncce36dca22015-04-21 22:11:2311995 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5311996 request.load_flags = 0;
11997
11998 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2311999 MockWrite(
12000 "GET / HTTP/1.1\r\n"
12001 "Host: www.example.org\r\n"
12002 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312003 };
12004
bnc1c196c6e2016-05-28 13:51:4812005 std::string alternative_service_http_header =
12006 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4312007
[email protected]65041fa2010-05-21 06:56:5312008 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212009 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4812010 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5212011 MockRead("\r\n"),
12012 MockRead("hello world"),
12013 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312014 };
12015
[email protected]8ddf8322012-02-23 18:08:0612016 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4812017 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5312018
[email protected]bb88e1d32013-05-03 23:11:0712019 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312020
12021 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12022 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712023 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312024
[email protected]49639fa2011-12-20 23:22:4112025 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312026
danakj1fd259a02016-04-16 03:17:0912027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12028 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012029 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5312030
[email protected]49639fa2011-12-20 23:22:4112031 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5312032
12033 EXPECT_EQ(ERR_IO_PENDING, rv);
12034 EXPECT_EQ(OK, callback.WaitForResult());
12035
12036 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212037 ASSERT_TRUE(response);
12038 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312039 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12040
12041 std::string response_data;
12042 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12043 EXPECT_EQ("hello world", response_data);
12044
12045 EXPECT_FALSE(response->was_fetched_via_spdy);
12046 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312047}
[email protected]26ef6582010-06-24 02:30:4712048
bnc55ff9da2015-08-19 18:42:3512049// Simulate the SSL handshake completing with an NPN negotiation followed by an
12050// immediate server closing of the socket.
12051// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0212052TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bncf33fb31b2016-01-29 15:22:2612053 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]26ef6582010-06-24 02:30:4712054
12055 HttpRequestInfo request;
12056 request.method = "GET";
bncce36dca22015-04-21 22:11:2312057 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712058 request.load_flags = 0;
12059
[email protected]8ddf8322012-02-23 18:08:0612060 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812061 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712062 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712063
danakj1fd259a02016-04-16 03:17:0912064 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912065 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1312066 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4712067
12068 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612069 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712070 };
12071
rch8e6c6c42015-05-01 14:05:1312072 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12073 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712074 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712075
[email protected]49639fa2011-12-20 23:22:4112076 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712077
danakj1fd259a02016-04-16 03:17:0912078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12079 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012080 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4712081
[email protected]49639fa2011-12-20 23:22:4112082 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4712083 EXPECT_EQ(ERR_IO_PENDING, rv);
12084 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4712085}
[email protected]65d34382010-07-01 18:12:2612086
[email protected]795cbf82013-07-22 09:37:2712087// A subclass of HttpAuthHandlerMock that records the request URL when
12088// it gets it. This is needed since the auth handler may get destroyed
12089// before we get a chance to query it.
12090class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12091 public:
12092 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12093
dchengb03027d2014-10-21 12:00:2012094 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712095
12096 protected:
dchengb03027d2014-10-21 12:00:2012097 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12098 const HttpRequestInfo* request,
12099 const CompletionCallback& callback,
12100 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712101 *url_ = request->url;
12102 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12103 credentials, request, callback, auth_token);
12104 }
12105
12106 private:
12107 GURL* url_;
12108};
12109
bnc55ff9da2015-08-19 18:42:3512110// This test ensures that the URL passed into the proxy is upgraded to https
12111// when doing an Alternate Protocol upgrade.
bnc1c196c6e2016-05-28 13:51:4812112TEST_P(HttpNetworkTransactionTest, SpdyAlternativeServiceThroughProxy) {
bncf33fb31b2016-01-29 15:22:2612113 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]f45c1ee2010-08-03 00:54:3012114
rdsmith82957ad2015-09-16 19:42:0312115 session_deps_.proxy_service =
12116 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112117 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712118 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2712119 GURL request_url;
12120 {
12121 HttpAuthHandlerMock::Factory* auth_factory =
12122 new HttpAuthHandlerMock::Factory();
12123 UrlRecordingHttpAuthHandlerMock* auth_handler =
12124 new UrlRecordingHttpAuthHandlerMock(&request_url);
12125 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12126 auth_factory->set_do_init_from_challenge(true);
12127 session_deps_.http_auth_handler_factory.reset(auth_factory);
12128 }
[email protected]f45c1ee2010-08-03 00:54:3012129
12130 HttpRequestInfo request;
12131 request.method = "GET";
bncce36dca22015-04-21 22:11:2312132 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3012133 request.load_flags = 0;
12134
12135 // First round goes unauthenticated through the proxy.
12136 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2312137 MockWrite(
12138 "GET http://www.example.org/ HTTP/1.1\r\n"
12139 "Host: www.example.org\r\n"
12140 "Proxy-Connection: keep-alive\r\n"
12141 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3012142 };
12143 MockRead data_reads_1[] = {
bnc1c196c6e2016-05-28 13:51:4812144 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12145 MockRead("HTTP/1.1 200 OK\r\n"),
12146 MockRead("Alt-Svc: "),
12147 MockRead(GetAlternateProtocolFromParam()),
12148 MockRead("=\":443\"\r\n"),
12149 MockRead("Proxy-Connection: close\r\n"),
12150 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3012151 };
12152 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
12153 data_writes_1, arraysize(data_writes_1));
12154
bncce36dca22015-04-21 22:11:2312155 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3012156 // Alternate-Protocol announcement in the first round. It fails due
12157 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2312158 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5912159 // Proxy-Authorization headers. There is then a SPDY request round.
12160 //
[email protected]fe3b7dc2012-02-03 19:52:0912161 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
12162 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
12163 // does a Disconnect and Connect on the same socket, rather than trying
12164 // to obtain a new one.
12165 //
[email protected]394816e92010-08-03 07:38:5912166 // NOTE: Originally, the proxy response to the second CONNECT request
12167 // simply returned another 407 so the unit test could skip the SSL connection
12168 // establishment and SPDY framing issues. Alas, the
12169 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3012170 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5912171
danakj1fd259a02016-04-16 03:17:0912172 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912173 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
danakj1fd259a02016-04-16 03:17:0912174 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5512175 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912176 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5512177 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3012178
[email protected]394816e92010-08-03 07:38:5912179 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2312180 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1312181 MockWrite(ASYNC, 0,
12182 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712183 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312184 "Proxy-Connection: keep-alive\r\n"
12185 "\r\n"),
[email protected]394816e92010-08-03 07:38:5912186
bncce36dca22015-04-21 22:11:2312187 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1312188 MockWrite(ASYNC, 2,
12189 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712190 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312191 "Proxy-Connection: keep-alive\r\n"
12192 "Proxy-Authorization: auth_token\r\n"
12193 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3012194
bncce36dca22015-04-21 22:11:2312195 // SPDY request
rch8e6c6c42015-05-01 14:05:1312196 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3012197 };
[email protected]394816e92010-08-03 07:38:5912198 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1312199 // First connection attempt fails
mmenkee71e15332015-10-07 16:39:5412200 MockRead(ASYNC, 1,
12201 "HTTP/1.1 407 Unauthorized\r\n"
12202 "Proxy-Authenticate: Mock\r\n"
12203 "Content-Length: 0\r\n"
12204 "Proxy-Connection: keep-alive\r\n"
12205 "\r\n"),
[email protected]394816e92010-08-03 07:38:5912206
rch8e6c6c42015-05-01 14:05:1312207 // Second connection attempt passes
mmenkee71e15332015-10-07 16:39:5412208 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5912209
rch8e6c6c42015-05-01 14:05:1312210 // SPDY response
mmenkee71e15332015-10-07 16:39:5412211 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1312212 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5912213 };
rch8e6c6c42015-05-01 14:05:1312214 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
12215 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3012216
[email protected]8ddf8322012-02-23 18:08:0612217 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812218 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2312219 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5212220 ASSERT_TRUE(ssl.cert);
[email protected]f45c1ee2010-08-03 00:54:3012221
[email protected]d973e99a2012-02-17 21:02:3612222 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512223 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12224 NULL, 0, NULL, 0);
12225 hanging_non_alternate_protocol_socket.set_connect_data(
12226 never_finishing_connect);
12227
[email protected]bb88e1d32013-05-03 23:11:0712228 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
12229 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
12230 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12231 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512232 &hanging_non_alternate_protocol_socket);
danakj1fd259a02016-04-16 03:17:0912233 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3012234
12235 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4112236 TestCompletionCallback callback_1;
danakj1fd259a02016-04-16 03:17:0912237 std::unique_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5012238 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4112239 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3012240 EXPECT_EQ(ERR_IO_PENDING, rv);
12241 EXPECT_EQ(OK, callback_1.WaitForResult());
12242
12243 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4112244 TestCompletionCallback callback_2;
danakj1fd259a02016-04-16 03:17:0912245 std::unique_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5012246 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4112247 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3012248 EXPECT_EQ(ERR_IO_PENDING, rv);
12249 EXPECT_EQ(OK, callback_2.WaitForResult());
12250 const HttpResponseInfo* response = trans_2->GetResponseInfo();
wezca1070932016-05-26 20:30:5212251 ASSERT_TRUE(response);
12252 ASSERT_TRUE(response->auth_challenge);
[email protected]f45c1ee2010-08-03 00:54:3012253
12254 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4112255 TestCompletionCallback callback_3;
12256 rv = trans_2->RestartWithAuth(
12257 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3012258 EXPECT_EQ(ERR_IO_PENDING, rv);
12259 EXPECT_EQ(OK, callback_3.WaitForResult());
12260
12261 // After all that work, these two lines (or actually, just the scheme) are
12262 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3012263 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2312264 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3012265
[email protected]029c83b62013-01-24 05:28:2012266 LoadTimingInfo load_timing_info;
12267 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
12268 TestLoadTimingNotReusedWithPac(load_timing_info,
12269 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3812270}
12271
12272// Test that if we cancel the transaction as the connection is completing, that
12273// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0212274TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812275 // Setup everything about the connection to complete synchronously, so that
12276 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12277 // for is the callback from the HttpStreamRequest.
12278 // Then cancel the transaction.
12279 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612280 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812281 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612282 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12283 MockRead(SYNCHRONOUS, "hello world"),
12284 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812285 };
12286
[email protected]8e6441ca2010-08-19 05:56:3812287 HttpRequestInfo request;
12288 request.method = "GET";
bncce36dca22015-04-21 22:11:2312289 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812290 request.load_flags = 0;
12291
[email protected]bb88e1d32013-05-03 23:11:0712292 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912293 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12294 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2712296
[email protected]8e6441ca2010-08-19 05:56:3812297 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12298 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712299 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812300
[email protected]49639fa2011-12-20 23:22:4112301 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812302
vishal.b62985ca92015-04-17 08:45:5112303 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112304 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3812305 EXPECT_EQ(ERR_IO_PENDING, rv);
12306 trans.reset(); // Cancel the transaction here.
12307
fdoray92e35a72016-06-10 15:54:5512308 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012309}
12310
[email protected]ecab6e052014-05-16 14:58:1212311// Test that if a transaction is cancelled after receiving the headers, the
12312// stream is drained properly and added back to the socket pool. The main
12313// purpose of this test is to make sure that an HttpStreamParser can be read
12314// from after the HttpNetworkTransaction and the objects it owns have been
12315// deleted.
12316// See http://crbug.com/368418
12317TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
12318 MockRead data_reads[] = {
12319 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12320 MockRead(ASYNC, "Content-Length: 2\r\n"),
12321 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12322 MockRead(ASYNC, "1"),
12323 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12324 // HttpNetworkTransaction has been deleted.
12325 MockRead(ASYNC, "2"),
12326 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12327 };
12328 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12329 session_deps_.socket_factory->AddSocketDataProvider(&data);
12330
danakj1fd259a02016-04-16 03:17:0912331 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212332
12333 {
12334 HttpRequestInfo request;
12335 request.method = "GET";
bncce36dca22015-04-21 22:11:2312336 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212337 request.load_flags = 0;
12338
dcheng48459ac22014-08-26 00:46:4112339 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212340 TestCompletionCallback callback;
12341
12342 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
12343 EXPECT_EQ(ERR_IO_PENDING, rv);
12344 callback.WaitForResult();
12345
12346 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212347 ASSERT_TRUE(response);
12348 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212349 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12350
12351 // The transaction and HttpRequestInfo are deleted.
12352 }
12353
12354 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512355 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212356
12357 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112358 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212359}
12360
[email protected]76a505b2010-08-25 06:23:0012361// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0212362TEST_P(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312363 session_deps_.proxy_service =
12364 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112365 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712366 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912367 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012368
[email protected]76a505b2010-08-25 06:23:0012369 HttpRequestInfo request;
12370 request.method = "GET";
bncce36dca22015-04-21 22:11:2312371 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012372
12373 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312374 MockWrite(
12375 "GET http://www.example.org/ HTTP/1.1\r\n"
12376 "Host: www.example.org\r\n"
12377 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012378 };
12379
12380 MockRead data_reads1[] = {
12381 MockRead("HTTP/1.1 200 OK\r\n"),
12382 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12383 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612384 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012385 };
12386
12387 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12388 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712389 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012390
[email protected]49639fa2011-12-20 23:22:4112391 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012392
danakj1fd259a02016-04-16 03:17:0912393 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012394 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ryansturm49a8cb12016-06-15 16:51:0912395 BeforeHeadersSentHandler headers_handler;
12396 trans->SetBeforeHeadersSentCallback(
12397 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12398 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012399
[email protected]49639fa2011-12-20 23:22:4112400 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012401 EXPECT_EQ(ERR_IO_PENDING, rv);
12402
12403 rv = callback1.WaitForResult();
12404 EXPECT_EQ(OK, rv);
12405
12406 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212407 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012408
12409 EXPECT_TRUE(response->headers->IsKeepAlive());
12410 EXPECT_EQ(200, response->headers->response_code());
12411 EXPECT_EQ(100, response->headers->GetContentLength());
12412 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512413 EXPECT_TRUE(
12414 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
ryansturm49a8cb12016-06-15 16:51:0912415 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12416 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12417 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012418 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012419
12420 LoadTimingInfo load_timing_info;
12421 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12422 TestLoadTimingNotReusedWithPac(load_timing_info,
12423 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012424}
12425
12426// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0212427TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312428 session_deps_.proxy_service =
12429 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112430 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712431 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912432 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012433
[email protected]76a505b2010-08-25 06:23:0012434 HttpRequestInfo request;
12435 request.method = "GET";
bncce36dca22015-04-21 22:11:2312436 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012437
12438 // Since we have proxy, should try to establish tunnel.
12439 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712440 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12441 "Host: www.example.org:443\r\n"
12442 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012443
rsleevidb16bb02015-11-12 23:47:1712444 MockWrite("GET / HTTP/1.1\r\n"
12445 "Host: www.example.org\r\n"
12446 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012447 };
12448
12449 MockRead data_reads1[] = {
12450 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12451
12452 MockRead("HTTP/1.1 200 OK\r\n"),
12453 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12454 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612455 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012456 };
12457
12458 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12459 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712460 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612461 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012463
[email protected]49639fa2011-12-20 23:22:4112464 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012465
danakj1fd259a02016-04-16 03:17:0912466 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012467 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ryansturm49a8cb12016-06-15 16:51:0912468 BeforeHeadersSentHandler headers_handler;
12469 trans->SetBeforeHeadersSentCallback(
12470 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12471 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012472
[email protected]49639fa2011-12-20 23:22:4112473 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012474 EXPECT_EQ(ERR_IO_PENDING, rv);
12475
12476 rv = callback1.WaitForResult();
12477 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4612478 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012479 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012480 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012481 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012482 NetLog::PHASE_NONE);
12483 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012484 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012485 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12486 NetLog::PHASE_NONE);
12487
12488 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212489 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012490
12491 EXPECT_TRUE(response->headers->IsKeepAlive());
12492 EXPECT_EQ(200, response->headers->response_code());
12493 EXPECT_EQ(100, response->headers->GetContentLength());
12494 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12495 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512496 EXPECT_TRUE(
12497 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
ryansturm49a8cb12016-06-15 16:51:0912498 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12499 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12500 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012501
12502 LoadTimingInfo load_timing_info;
12503 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12504 TestLoadTimingNotReusedWithPac(load_timing_info,
12505 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012506}
12507
rsleevidb16bb02015-11-12 23:47:1712508// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12509// literal host.
12510TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
12511 session_deps_.proxy_service =
12512 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12513 BoundTestNetLog log;
12514 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912515 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712516
12517 HttpRequestInfo request;
12518 request.method = "GET";
12519 request.url = GURL("https://[::1]:443/");
12520
12521 // Since we have proxy, should try to establish tunnel.
12522 MockWrite data_writes1[] = {
12523 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12524 "Host: [::1]:443\r\n"
12525 "Proxy-Connection: keep-alive\r\n\r\n"),
12526
12527 MockWrite("GET / HTTP/1.1\r\n"
12528 "Host: [::1]\r\n"
12529 "Connection: keep-alive\r\n\r\n"),
12530 };
12531
12532 MockRead data_reads1[] = {
12533 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12534
12535 MockRead("HTTP/1.1 200 OK\r\n"),
12536 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12537 MockRead("Content-Length: 100\r\n\r\n"),
12538 MockRead(SYNCHRONOUS, OK),
12539 };
12540
12541 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12542 data_writes1, arraysize(data_writes1));
12543 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12544 SSLSocketDataProvider ssl(ASYNC, OK);
12545 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12546
12547 TestCompletionCallback callback1;
12548
danakj1fd259a02016-04-16 03:17:0912549 std::unique_ptr<HttpTransaction> trans(
rsleevidb16bb02015-11-12 23:47:1712550 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12551
12552 int rv = trans->Start(&request, callback1.callback(), log.bound());
12553 EXPECT_EQ(ERR_IO_PENDING, rv);
12554
12555 rv = callback1.WaitForResult();
12556 EXPECT_EQ(OK, rv);
12557 TestNetLogEntry::List entries;
12558 log.GetEntries(&entries);
12559 size_t pos = ExpectLogContainsSomewhere(
12560 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12561 NetLog::PHASE_NONE);
12562 ExpectLogContainsSomewhere(
12563 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12564 NetLog::PHASE_NONE);
12565
12566 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212567 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712568
12569 EXPECT_TRUE(response->headers->IsKeepAlive());
12570 EXPECT_EQ(200, response->headers->response_code());
12571 EXPECT_EQ(100, response->headers->GetContentLength());
12572 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12573 EXPECT_TRUE(response->was_fetched_via_proxy);
12574 EXPECT_TRUE(
12575 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
12576
12577 LoadTimingInfo load_timing_info;
12578 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12579 TestLoadTimingNotReusedWithPac(load_timing_info,
12580 CONNECT_TIMING_HAS_SSL_TIMES);
12581}
12582
[email protected]76a505b2010-08-25 06:23:0012583// Test a basic HTTPS GET request through a proxy, but the server hangs up
12584// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0212585TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312586 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112587 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712588 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912589 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012590
[email protected]76a505b2010-08-25 06:23:0012591 HttpRequestInfo request;
12592 request.method = "GET";
bncce36dca22015-04-21 22:11:2312593 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012594
12595 // Since we have proxy, should try to establish tunnel.
12596 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712597 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12598 "Host: www.example.org:443\r\n"
12599 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012600
rsleevidb16bb02015-11-12 23:47:1712601 MockWrite("GET / HTTP/1.1\r\n"
12602 "Host: www.example.org\r\n"
12603 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012604 };
12605
12606 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0612607 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0012608 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612609 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0012610 };
12611
12612 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12613 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712614 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612615 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712616 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012617
[email protected]49639fa2011-12-20 23:22:4112618 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012619
danakj1fd259a02016-04-16 03:17:0912620 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012621 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5012622
[email protected]49639fa2011-12-20 23:22:4112623 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012624 EXPECT_EQ(ERR_IO_PENDING, rv);
12625
12626 rv = callback1.WaitForResult();
12627 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4612628 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012629 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012630 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012631 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012632 NetLog::PHASE_NONE);
12633 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012634 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012635 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12636 NetLog::PHASE_NONE);
12637}
12638
[email protected]749eefa82010-09-13 22:14:0312639// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0212640TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
danakj1fd259a02016-04-16 03:17:0912641 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912642 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1312643 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0312644
danakj1fd259a02016-04-16 03:17:0912645 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5512646 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912647 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5512648 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0312649 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312650 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0312651 };
12652
rch8e6c6c42015-05-01 14:05:1312653 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12654 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712655 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0312656
[email protected]8ddf8322012-02-23 18:08:0612657 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812658 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712659 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0312660
danakj1fd259a02016-04-16 03:17:0912661 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0312662
12663 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2312664 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012665 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312666 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712667 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4212668 CreateInsecureSpdySession(session.get(), key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312669
12670 HttpRequestInfo request;
12671 request.method = "GET";
bncce36dca22015-04-21 22:11:2312672 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0312673 request.load_flags = 0;
12674
12675 // This is the important line that marks this as a preconnect.
12676 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
12677
danakj1fd259a02016-04-16 03:17:0912678 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012679 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0312680
[email protected]41d64e82013-07-03 22:44:2612681 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4112682 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312683 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112684 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0312685}
12686
[email protected]73b8dd222010-11-11 19:55:2412687// Given a net error, cause that error to be returned from the first Write()
12688// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0212689void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0712690 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2912691 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712692 request_info.url = GURL("https://www.example.com/");
12693 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912694 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712695
[email protected]8ddf8322012-02-23 18:08:0612696 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2912697 MockWrite data_writes[] = {
12698 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2412699 };
ttuttle859dc7a2015-04-23 19:42:2912700 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712701 session_deps_.socket_factory->AddSocketDataProvider(&data);
12702 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2412703
danakj1fd259a02016-04-16 03:17:0912704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12705 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012706 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2412707
[email protected]49639fa2011-12-20 23:22:4112708 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912709 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12710 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2412711 rv = callback.WaitForResult();
12712 ASSERT_EQ(error, rv);
12713}
12714
[email protected]23e482282013-06-14 16:08:0212715TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2412716 // Just check a grab bag of cert errors.
12717 static const int kErrors[] = {
12718 ERR_CERT_COMMON_NAME_INVALID,
12719 ERR_CERT_AUTHORITY_INVALID,
12720 ERR_CERT_DATE_INVALID,
12721 };
12722 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0612723 CheckErrorIsPassedBack(kErrors[i], ASYNC);
12724 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2412725 }
12726}
12727
[email protected]bd0b6772011-01-11 19:59:3012728// Ensure that a client certificate is removed from the SSL client auth
12729// cache when:
12730// 1) No proxy is involved.
12731// 2) TLS False Start is disabled.
12732// 3) The initial TLS handshake requests a client certificate.
12733// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212734TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312735 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912736 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712737 request_info.url = GURL("https://www.example.com/");
12738 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912739 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712740
[email protected]bd0b6772011-01-11 19:59:3012741 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112742 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012743
12744 // [ssl_]data1 contains the data for the first SSL handshake. When a
12745 // CertificateRequest is received for the first time, the handshake will
12746 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2912747 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012748 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712749 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912750 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712751 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012752
12753 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
12754 // False Start is not being used, the result of the SSL handshake will be
12755 // returned as part of the SSLClientSocket::Connect() call. This test
12756 // matches the result of a server sending a handshake_failure alert,
12757 // rather than a Finished message, because it requires a client
12758 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2912759 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012760 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712761 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912762 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712763 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012764
12765 // [ssl_]data3 contains the data for the third SSL handshake. When a
12766 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212767 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
12768 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3012769 // of the HttpNetworkTransaction. Because this test failure is due to
12770 // requiring a client certificate, this fallback handshake should also
12771 // fail.
ttuttle859dc7a2015-04-23 19:42:2912772 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012773 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712774 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912775 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712776 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012777
[email protected]80c75f682012-05-26 16:22:1712778 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
12779 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212780 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
12781 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1712782 // of the HttpNetworkTransaction. Because this test failure is due to
12783 // requiring a client certificate, this fallback handshake should also
12784 // fail.
ttuttle859dc7a2015-04-23 19:42:2912785 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1712786 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712787 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912788 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712789 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712790
danakj1fd259a02016-04-16 03:17:0912791 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12792 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012793 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012794
[email protected]bd0b6772011-01-11 19:59:3012795 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4112796 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912797 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12798 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012799
12800 // Complete the SSL handshake, which should abort due to requiring a
12801 // client certificate.
12802 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912803 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012804
12805 // Indicate that no certificate should be supplied. From the perspective
12806 // of SSLClientCertCache, NULL is just as meaningful as a real
12807 // certificate, so this is the same as supply a
12808 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412809 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912810 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012811
12812 // Ensure the certificate was added to the client auth cache before
12813 // allowing the connection to continue restarting.
12814 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412815 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112816 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412817 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212818 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012819
12820 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712821 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12822 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012823 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912824 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012825
12826 // Ensure that the client certificate is removed from the cache on a
12827 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112828 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412829 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012830}
12831
12832// Ensure that a client certificate is removed from the SSL client auth
12833// cache when:
12834// 1) No proxy is involved.
12835// 2) TLS False Start is enabled.
12836// 3) The initial TLS handshake requests a client certificate.
12837// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212838TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312839 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912840 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712841 request_info.url = GURL("https://www.example.com/");
12842 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912843 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712844
[email protected]bd0b6772011-01-11 19:59:3012845 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112846 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012847
12848 // When TLS False Start is used, SSLClientSocket::Connect() calls will
12849 // return successfully after reading up to the peer's Certificate message.
12850 // This is to allow the caller to call SSLClientSocket::Write(), which can
12851 // enqueue application data to be sent in the same packet as the
12852 // ChangeCipherSpec and Finished messages.
12853 // The actual handshake will be finished when SSLClientSocket::Read() is
12854 // called, which expects to process the peer's ChangeCipherSpec and
12855 // Finished messages. If there was an error negotiating with the peer,
12856 // such as due to the peer requiring a client certificate when none was
12857 // supplied, the alert sent by the peer won't be processed until Read() is
12858 // called.
12859
12860 // Like the non-False Start case, when a client certificate is requested by
12861 // the peer, the handshake is aborted during the Connect() call.
12862 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2912863 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012864 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712865 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912866 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712867 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012868
12869 // When a client certificate is supplied, Connect() will not be aborted
12870 // when the peer requests the certificate. Instead, the handshake will
12871 // artificially succeed, allowing the caller to write the HTTP request to
12872 // the socket. The handshake messages are not processed until Read() is
12873 // called, which then detects that the handshake was aborted, due to the
12874 // peer sending a handshake_failure because it requires a client
12875 // certificate.
ttuttle859dc7a2015-04-23 19:42:2912876 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012877 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712878 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912879 MockRead data2_reads[] = {
12880 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3012881 };
ttuttle859dc7a2015-04-23 19:42:2912882 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712883 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012884
12885 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1712886 // the data for the SSL handshake once the TLSv1.1 connection falls back to
12887 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912888 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012889 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712890 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912891 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712892 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012893
[email protected]80c75f682012-05-26 16:22:1712894 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
12895 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912896 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1712897 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712898 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912899 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712900 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712901
[email protected]7799de12013-05-30 05:52:5112902 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2912903 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5112904 ssl_data5.cert_request_info = cert_request.get();
12905 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2912906 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5112907 session_deps_.socket_factory->AddSocketDataProvider(&data5);
12908
danakj1fd259a02016-04-16 03:17:0912909 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12910 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012911 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012912
[email protected]bd0b6772011-01-11 19:59:3012913 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4112914 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912915 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12916 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012917
12918 // Complete the SSL handshake, which should abort due to requiring a
12919 // client certificate.
12920 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912921 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012922
12923 // Indicate that no certificate should be supplied. From the perspective
12924 // of SSLClientCertCache, NULL is just as meaningful as a real
12925 // certificate, so this is the same as supply a
12926 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412927 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912928 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012929
12930 // Ensure the certificate was added to the client auth cache before
12931 // allowing the connection to continue restarting.
12932 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412933 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112934 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412935 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212936 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012937
[email protected]bd0b6772011-01-11 19:59:3012938 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712939 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12940 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012941 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912942 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012943
12944 // Ensure that the client certificate is removed from the cache on a
12945 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112946 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412947 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012948}
12949
[email protected]8c405132011-01-11 22:03:1812950// Ensure that a client certificate is removed from the SSL client auth
12951// cache when:
12952// 1) An HTTPS proxy is involved.
12953// 3) The HTTPS proxy requests a client certificate.
12954// 4) The client supplies an invalid/unacceptable certificate for the
12955// proxy.
12956// The test is repeated twice, first for connecting to an HTTPS endpoint,
12957// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0212958TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0312959 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5112960 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712961 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1812962
12963 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112964 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1812965
12966 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
12967 // [ssl_]data[1-3]. Rather than represending the endpoint
12968 // (www.example.com:443), they represent failures with the HTTPS proxy
12969 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2912970 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1812971 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712972 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912973 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712974 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1812975
ttuttle859dc7a2015-04-23 19:42:2912976 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812977 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712978 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912979 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712980 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1812981
[email protected]80c75f682012-05-26 16:22:1712982 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
12983#if 0
ttuttle859dc7a2015-04-23 19:42:2912984 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812985 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712986 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912987 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712988 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1712989#endif
[email protected]8c405132011-01-11 22:03:1812990
ttuttle859dc7a2015-04-23 19:42:2912991 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1812992 requests[0].url = GURL("https://www.example.com/");
12993 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912994 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812995
12996 requests[1].url = GURL("http://www.example.com/");
12997 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912998 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812999
13000 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713001 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913002 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13003 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013004 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1813005
13006 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113007 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2913008 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
13009 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1813010
13011 // Complete the SSL handshake, which should abort due to requiring a
13012 // client certificate.
13013 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2913014 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1813015
13016 // Indicate that no certificate should be supplied. From the perspective
13017 // of SSLClientCertCache, NULL is just as meaningful as a real
13018 // certificate, so this is the same as supply a
13019 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5413020 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2913021 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1813022
13023 // Ensure the certificate was added to the client auth cache before
13024 // allowing the connection to continue restarting.
13025 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413026 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113027 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413028 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213029 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813030 // Ensure the certificate was NOT cached for the endpoint. This only
13031 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113032 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413033 HostPortPair("www.example.com", 443), &client_cert,
13034 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813035
13036 // Restart the handshake. This will consume ssl_data2, which fails, and
13037 // then consume ssl_data3, which should also fail. The result code is
13038 // checked against what ssl_data3 should return.
13039 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2913040 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1813041
13042 // Now that the new handshake has failed, ensure that the client
13043 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113044 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413045 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113046 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413047 HostPortPair("www.example.com", 443), &client_cert,
13048 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813049 }
13050}
13051
mmenke5c642132015-06-02 16:05:1313052TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bncf33fb31b2016-01-29 15:22:2613053 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4613054
13055 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713056 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913057 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2613058 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
13059 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4613060
[email protected]8ddf8322012-02-23 18:08:0613061 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813062 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713063 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4613064
danakj1fd259a02016-04-16 03:17:0913065 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913066 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813067 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0913068 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913069 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613070 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313071 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613072 };
danakj1fd259a02016-04-16 03:17:0913073 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213074 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913075 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213076 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913077 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0213078 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913079 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0213080 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613081 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1313082 CreateMockRead(*host1_resp, 1),
13083 CreateMockRead(*host1_resp_body, 2),
13084 CreateMockRead(*host2_resp, 4),
13085 CreateMockRead(*host2_resp_body, 5),
13086 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613087 };
13088
eroman36d84e54432016-03-17 03:23:0213089 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213090 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313091 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13092 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713093 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613094
[email protected]aa22b242011-11-16 18:58:2913095 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613096 HttpRequestInfo request1;
13097 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313098 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613099 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013100 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613101
[email protected]49639fa2011-12-20 23:22:4113102 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613103 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113104 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613105
13106 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213107 ASSERT_TRUE(response);
13108 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213109 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613110
13111 std::string response_data;
13112 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
13113 EXPECT_EQ("hello!", response_data);
13114
13115 // Preload www.gmail.com into HostCache.
13116 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1013117 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613118 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1013119 rv = session_deps_.host_resolver->Resolve(resolve_info,
13120 DEFAULT_PRIORITY,
13121 &ignored,
13122 callback.callback(),
13123 NULL,
13124 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4713125 EXPECT_EQ(ERR_IO_PENDING, rv);
13126 rv = callback.WaitForResult();
13127 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4613128
13129 HttpRequestInfo request2;
13130 request2.method = "GET";
13131 request2.url = GURL("https://www.gmail.com/");
13132 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013133 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613134
[email protected]49639fa2011-12-20 23:22:4113135 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613136 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113137 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613138
13139 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213140 ASSERT_TRUE(response);
13141 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213142 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613143 EXPECT_TRUE(response->was_fetched_via_spdy);
13144 EXPECT_TRUE(response->was_npn_negotiated);
13145 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
13146 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613147}
13148
[email protected]23e482282013-06-14 16:08:0213149TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bncf33fb31b2016-01-29 15:22:2613150 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d2b5f092012-06-08 23:55:0213151
13152 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713153 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913154 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213155 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
13156 pool_peer.DisableDomainAuthenticationVerification();
13157
13158 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813159 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713160 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0213161
danakj1fd259a02016-04-16 03:17:0913162 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913163 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813164 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0913165 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913166 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213167 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313168 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213169 };
danakj1fd259a02016-04-16 03:17:0913170 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213171 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913172 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213173 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913174 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0213175 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913176 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0213177 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213178 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1313179 CreateMockRead(*host1_resp, 1),
13180 CreateMockRead(*host1_resp_body, 2),
13181 CreateMockRead(*host2_resp, 4),
13182 CreateMockRead(*host2_resp_body, 5),
13183 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213184 };
13185
eroman36d84e54432016-03-17 03:23:0213186 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213187 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313188 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13189 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713190 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213191
13192 TestCompletionCallback callback;
13193 HttpRequestInfo request1;
13194 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313195 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213196 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013197 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213198
13199 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
13200 EXPECT_EQ(ERR_IO_PENDING, rv);
13201 EXPECT_EQ(OK, callback.WaitForResult());
13202
13203 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213204 ASSERT_TRUE(response);
13205 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213206 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213207
13208 std::string response_data;
13209 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
13210 EXPECT_EQ("hello!", response_data);
13211
13212 HttpRequestInfo request2;
13213 request2.method = "GET";
13214 request2.url = GURL("https://www.gmail.com/");
13215 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013216 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213217
13218 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
13219 EXPECT_EQ(ERR_IO_PENDING, rv);
13220 EXPECT_EQ(OK, callback.WaitForResult());
13221
13222 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213223 ASSERT_TRUE(response);
13224 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213225 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213226 EXPECT_TRUE(response->was_fetched_via_spdy);
13227 EXPECT_TRUE(response->was_npn_negotiated);
13228 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
13229 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213230}
13231
ttuttle859dc7a2015-04-23 19:42:2913232class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4613233 public:
13234 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
13235 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013236 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613237
13238 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
13239
13240 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2013241 int Resolve(const RequestInfo& info,
13242 RequestPriority priority,
13243 AddressList* addresses,
13244 const CompletionCallback& callback,
13245 RequestHandle* out_req,
13246 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013247 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1013248 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4013249 }
13250
dchengb03027d2014-10-21 12:00:2013251 int ResolveFromCache(const RequestInfo& info,
13252 AddressList* addresses,
13253 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013254 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
13255 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0913256 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613257 return rv;
13258 }
13259
dchengb03027d2014-10-21 12:00:2013260 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4613261 host_resolver_.CancelRequest(req);
13262 }
13263
[email protected]46da33be2011-07-19 21:58:0413264 MockCachingHostResolver* GetMockHostResolver() {
13265 return &host_resolver_;
13266 }
13267
[email protected]e3ceb682011-06-28 23:55:4613268 private:
13269 MockCachingHostResolver host_resolver_;
13270 const HostPortPair host_port_;
13271};
13272
mmenke5c642132015-06-02 16:05:1313273TEST_P(HttpNetworkTransactionTest,
13274 UseIPConnectionPoolingWithHostCacheExpiration) {
bncf33fb31b2016-01-29 15:22:2613275 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4613276
13277 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4613278 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3413279 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0713280 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4613281 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0913282 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2613283 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
13284 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4613285
[email protected]8ddf8322012-02-23 18:08:0613286 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813287 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4613289
danakj1fd259a02016-04-16 03:17:0913290 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913291 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813292 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0913293 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913294 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613295 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313296 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613297 };
danakj1fd259a02016-04-16 03:17:0913298 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213299 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913300 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213301 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913302 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0213303 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913304 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0213305 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613306 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1313307 CreateMockRead(*host1_resp, 1),
13308 CreateMockRead(*host1_resp_body, 2),
13309 CreateMockRead(*host2_resp, 4),
13310 CreateMockRead(*host2_resp_body, 5),
13311 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613312 };
13313
eroman36d84e54432016-03-17 03:23:0213314 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213315 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313316 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13317 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713318 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613319
[email protected]aa22b242011-11-16 18:58:2913320 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613321 HttpRequestInfo request1;
13322 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313323 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613324 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013325 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613326
[email protected]49639fa2011-12-20 23:22:4113327 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613328 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113329 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613330
13331 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213332 ASSERT_TRUE(response);
13333 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213334 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613335
13336 std::string response_data;
13337 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
13338 EXPECT_EQ("hello!", response_data);
13339
13340 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1013341 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613342 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1013343 rv = host_resolver.Resolve(resolve_info,
13344 DEFAULT_PRIORITY,
13345 &ignored,
13346 callback.callback(),
13347 NULL,
13348 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4713349 EXPECT_EQ(ERR_IO_PENDING, rv);
13350 rv = callback.WaitForResult();
13351 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4613352
13353 HttpRequestInfo request2;
13354 request2.method = "GET";
13355 request2.url = GURL("https://www.gmail.com/");
13356 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013357 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613358
[email protected]49639fa2011-12-20 23:22:4113359 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613360 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113361 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613362
13363 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213364 ASSERT_TRUE(response);
13365 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213366 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613367 EXPECT_TRUE(response->was_fetched_via_spdy);
13368 EXPECT_TRUE(response->was_npn_negotiated);
13369 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
13370 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613371}
13372
[email protected]23e482282013-06-14 16:08:0213373TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313374 const std::string https_url = "https://www.example.org:8080/";
13375 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413376
13377 // SPDY GET for HTTPS URL
danakj1fd259a02016-04-16 03:17:0913378 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913379 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413380
13381 MockWrite writes1[] = {
13382 CreateMockWrite(*req1, 0),
13383 };
13384
danakj1fd259a02016-04-16 03:17:0913385 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5513386 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913387 std::unique_ptr<SpdySerializedFrame> body1(
bncb03b1092016-04-06 11:19:5513388 spdy_util_.ConstructSpdyBodyFrame(1, true));
mmenkee24011922015-12-17 22:12:5913389 MockRead reads1[] = {CreateMockRead(*resp1, 1), CreateMockRead(*body1, 2),
13390 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413391
rch8e6c6c42015-05-01 14:05:1313392 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13393 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413394 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713395 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413396
13397 // HTTP GET for the HTTP URL
13398 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313399 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413400 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313401 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413402 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413403 };
13404
13405 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313406 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13407 MockRead(ASYNC, 2, "hello"),
13408 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413409 };
13410
rch8e6c6c42015-05-01 14:05:1313411 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13412 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413413
[email protected]8450d722012-07-02 19:14:0413414 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813415 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713416 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13417 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13418 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413419
danakj1fd259a02016-04-16 03:17:0913420 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413421
13422 // Start the first transaction to set up the SpdySession
13423 HttpRequestInfo request1;
13424 request1.method = "GET";
13425 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413426 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013427 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413428 TestCompletionCallback callback1;
13429 EXPECT_EQ(ERR_IO_PENDING,
13430 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5513431 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413432
13433 EXPECT_EQ(OK, callback1.WaitForResult());
13434 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13435
13436 // Now, start the HTTP request
13437 HttpRequestInfo request2;
13438 request2.method = "GET";
13439 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413440 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013441 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413442 TestCompletionCallback callback2;
13443 EXPECT_EQ(ERR_IO_PENDING,
13444 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5513445 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413446
13447 EXPECT_EQ(OK, callback2.WaitForResult());
13448 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13449}
13450
bnc1b0e36852015-04-28 15:32:5913451class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
13452 public:
13453 void Run(bool pooling, bool valid) {
zhongyi3d4a55e72016-04-22 20:36:4613454 url::SchemeHostPort server(GURL(valid ? "https://mail.example.org:443"
13455 : "https://invalid.example.org:443"));
bnc1b0e36852015-04-28 15:32:5913456 HostPortPair alternative("www.example.org", 443);
13457
13458 base::FilePath certs_dir = GetTestCertsDirectory();
13459 scoped_refptr<X509Certificate> cert(
13460 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
wezca1070932016-05-26 20:30:5213461 ASSERT_TRUE(cert);
bnc1b0e36852015-04-28 15:32:5913462 bool common_name_fallback_used;
13463 EXPECT_EQ(valid,
zhongyi3d4a55e72016-04-22 20:36:4613464 cert->VerifyNameMatch(server.host(), &common_name_fallback_used));
bnc1b0e36852015-04-28 15:32:5913465 EXPECT_TRUE(
13466 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
13467 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813468 ssl.SetNextProto(GetProtocol());
bnc1b0e36852015-04-28 15:32:5913469 ssl.cert = cert;
13470 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13471
13472 // If pooling, then start a request to alternative first to create a
13473 // SpdySession.
13474 std::string url0 = "https://www.example.org:443";
zhongyi3d4a55e72016-04-22 20:36:4613475 // Second request to server, which has an alternative service, and could
bnc1b0e36852015-04-28 15:32:5913476 // open a connection to the alternative host or pool to the existing one.
13477 std::string url1("https://");
zhongyi3d4a55e72016-04-22 20:36:4613478 url1.append(server.host());
bnc1b0e36852015-04-28 15:32:5913479 url1.append(":443");
13480
danakj1fd259a02016-04-16 03:17:0913481 std::unique_ptr<SpdySerializedFrame> req0;
13482 std::unique_ptr<SpdySerializedFrame> req1;
13483 std::unique_ptr<SpdySerializedFrame> resp0;
13484 std::unique_ptr<SpdySerializedFrame> body0;
13485 std::unique_ptr<SpdySerializedFrame> resp1;
13486 std::unique_ptr<SpdySerializedFrame> body1;
bnc1b0e36852015-04-28 15:32:5913487 std::vector<MockWrite> writes;
13488 std::vector<MockRead> reads;
13489
13490 if (pooling) {
bnc38dcd392016-02-09 23:19:4913491 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813492 spdy_util_.UpdateWithStreamDestruction(1);
bnc38dcd392016-02-09 23:19:4913493 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 3, LOWEST));
bnc1b0e36852015-04-28 15:32:5913494
13495 writes.push_back(CreateMockWrite(*req0, 0));
13496 writes.push_back(CreateMockWrite(*req1, 3));
13497
13498 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13499 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13500 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
13501 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
13502
13503 reads.push_back(CreateMockRead(*resp0, 1));
13504 reads.push_back(CreateMockRead(*body0, 2));
13505 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
13506 reads.push_back(CreateMockRead(*resp1, 5));
13507 reads.push_back(CreateMockRead(*body1, 6));
13508 reads.push_back(MockRead(ASYNC, OK, 7));
13509 } else {
bnc38dcd392016-02-09 23:19:4913510 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 1, LOWEST));
bnc1b0e36852015-04-28 15:32:5913511
13512 writes.push_back(CreateMockWrite(*req1, 0));
13513
13514 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13515 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13516
13517 reads.push_back(CreateMockRead(*resp1, 1));
13518 reads.push_back(CreateMockRead(*body1, 2));
13519 reads.push_back(MockRead(ASYNC, OK, 3));
13520 }
13521
davidben5f8b6bc2015-11-25 03:19:5413522 SequencedSocketData data(reads.data(), reads.size(), writes.data(),
13523 writes.size());
bnc1b0e36852015-04-28 15:32:5913524 session_deps_.socket_factory->AddSocketDataProvider(&data);
13525
zhongyi3d4a55e72016-04-22 20:36:4613526 // Connection to the server fails.
bnc1b0e36852015-04-28 15:32:5913527 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13528 StaticSocketDataProvider data_refused;
13529 data_refused.set_connect_data(mock_connect);
13530 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13531
bncf33fb31b2016-01-29 15:22:2613532 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913533 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc1b0e36852015-04-28 15:32:5913534 base::WeakPtr<HttpServerProperties> http_server_properties =
13535 session->http_server_properties();
13536 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813537 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213538 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613539 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013540 expiration);
bnc1b0e36852015-04-28 15:32:5913541
13542 // First request to alternative.
13543 if (pooling) {
danakj1fd259a02016-04-16 03:17:0913544 std::unique_ptr<HttpTransaction> trans0(
bnc1b0e36852015-04-28 15:32:5913545 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13546 HttpRequestInfo request0;
13547 request0.method = "GET";
13548 request0.url = GURL(url0);
13549 request0.load_flags = 0;
13550 TestCompletionCallback callback0;
13551
13552 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
13553 EXPECT_EQ(ERR_IO_PENDING, rv);
13554 rv = callback0.WaitForResult();
13555 EXPECT_EQ(OK, rv);
13556 }
13557
13558 // Second request to origin.
danakj1fd259a02016-04-16 03:17:0913559 std::unique_ptr<HttpTransaction> trans1(
bnc1b0e36852015-04-28 15:32:5913560 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13561 HttpRequestInfo request1;
13562 request1.method = "GET";
13563 request1.url = GURL(url1);
13564 request1.load_flags = 0;
13565 TestCompletionCallback callback1;
13566
13567 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13568 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:5513569 base::RunLoop().RunUntilIdle();
mmenkee24011922015-12-17 22:12:5913570 if (data.IsPaused())
13571 data.Resume();
bnc1b0e36852015-04-28 15:32:5913572 rv = callback1.WaitForResult();
13573 if (valid) {
13574 EXPECT_EQ(OK, rv);
13575 } else {
13576 if (pooling) {
13577 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13578 } else {
13579 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
13580 }
13581 }
13582 }
13583};
13584
rdsmithebb50aa2015-11-12 03:44:3813585INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc1b0e36852015-04-28 15:32:5913586 AltSvcCertificateVerificationTest,
rdsmithebb50aa2015-11-12 03:44:3813587 testing::Values(kTestCaseSPDY31,
13588 kTestCaseHTTP2NoPriorityDependencies,
13589 kTestCaseHTTP2PriorityDependencies));
bnc1b0e36852015-04-28 15:32:5913590
13591// The alternative service host must exhibit a certificate that is valid for the
13592// origin host. Test that this is enforced when pooling to an existing
13593// connection.
13594TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
13595 Run(true, true);
13596}
13597
13598TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
13599 Run(true, false);
13600}
13601
13602// The alternative service host must exhibit a certificate that is valid for the
13603// origin host. Test that this is enforced when opening a new connection.
13604TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
13605 Run(false, true);
13606}
13607
bnc8bef8da22016-05-30 01:28:2513608// TODO(bnc): Re-enable when https://crbug.com/615413 is fixed.
13609TEST_P(AltSvcCertificateVerificationTest, DISABLED_NewConnectionInvalid) {
bnc1b0e36852015-04-28 15:32:5913610 Run(false, false);
13611}
13612
bnc5452e2a2015-05-08 16:27:4213613// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13614// with the alternative server. That connection should not be used.
13615TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2513616 url::SchemeHostPort server("https", "www.example.org", 443);
13617 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4213618
bnc8bef8da22016-05-30 01:28:2513619 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4213620 SSLSocketDataProvider ssl(ASYNC, OK);
13621 ssl.SetNextProto(kProtoHTTP11);
13622 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13623
13624 // No data should be read from the alternative, because HTTP/1.1 is
13625 // negotiated.
13626 StaticSocketDataProvider data;
13627 session_deps_.socket_factory->AddSocketDataProvider(&data);
13628
13629 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4613630 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4213631 // mocked. This way the request relies on the alternate Job.
13632 StaticSocketDataProvider data_refused;
13633 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13634 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13635
zhongyi3d4a55e72016-04-22 20:36:4613636 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613637 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913638 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213639 base::WeakPtr<HttpServerProperties> http_server_properties =
13640 session->http_server_properties();
13641 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813642 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213643 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613644 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013645 expiration);
bnc5452e2a2015-05-08 16:27:4213646
danakj1fd259a02016-04-16 03:17:0913647 std::unique_ptr<HttpTransaction> trans(
bnc5452e2a2015-05-08 16:27:4213648 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13649 HttpRequestInfo request;
13650 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2513651 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4213652 request.load_flags = 0;
13653 TestCompletionCallback callback;
13654
13655 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
13656 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
13657 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13658 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
13659}
13660
bnc40448a532015-05-11 19:13:1413661// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4613662// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1413663// succeeds, the request should succeed, even if the latter fails because
13664// HTTP/1.1 is negotiated which is insufficient for alternative service.
13665TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2513666 url::SchemeHostPort server("https", "www.example.org", 443);
13667 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1413668
13669 // Negotiate HTTP/1.1 with alternative.
13670 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
13671 alternative_ssl.SetNextProto(kProtoHTTP11);
13672 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13673
13674 // No data should be read from the alternative, because HTTP/1.1 is
13675 // negotiated.
13676 StaticSocketDataProvider data;
13677 session_deps_.socket_factory->AddSocketDataProvider(&data);
13678
zhongyi3d4a55e72016-04-22 20:36:4613679 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1413680 SSLSocketDataProvider origin_ssl(ASYNC, OK);
13681 origin_ssl.SetNextProto(kProtoHTTP11);
13682 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13683
13684 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2513685 MockWrite("GET / HTTP/1.1\r\n"
13686 "Host: www.example.org\r\n"
13687 "Connection: keep-alive\r\n\r\n"),
13688 MockWrite("GET /second HTTP/1.1\r\n"
13689 "Host: www.example.org\r\n"
13690 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1413691 };
13692
13693 MockRead http_reads[] = {
13694 MockRead("HTTP/1.1 200 OK\r\n"),
13695 MockRead("Content-Type: text/html\r\n"),
13696 MockRead("Content-Length: 6\r\n\r\n"),
13697 MockRead("foobar"),
13698 MockRead("HTTP/1.1 200 OK\r\n"),
13699 MockRead("Content-Type: text/html\r\n"),
13700 MockRead("Content-Length: 7\r\n\r\n"),
13701 MockRead("another"),
13702 };
13703 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13704 http_writes, arraysize(http_writes));
13705 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13706
zhongyi3d4a55e72016-04-22 20:36:4613707 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613708 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913709 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc40448a532015-05-11 19:13:1413710 base::WeakPtr<HttpServerProperties> http_server_properties =
13711 session->http_server_properties();
13712 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813713 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213714 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613715 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013716 expiration);
bnc40448a532015-05-11 19:13:1413717
13718 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13719 HttpRequestInfo request1;
13720 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2513721 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1413722 request1.load_flags = 0;
13723 TestCompletionCallback callback1;
13724
13725 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
13726 rv = callback1.GetResult(rv);
13727 EXPECT_EQ(OK, rv);
13728
13729 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213730 ASSERT_TRUE(response1);
13731 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1413732 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13733
13734 std::string response_data1;
13735 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
13736 EXPECT_EQ("foobar", response_data1);
13737
13738 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13739 // for alternative service.
13740 EXPECT_TRUE(
13741 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13742
zhongyi3d4a55e72016-04-22 20:36:4613743 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1413744 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4613745 // to server.
bnc40448a532015-05-11 19:13:1413746 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13747 HttpRequestInfo request2;
13748 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2513749 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1413750 request2.load_flags = 0;
13751 TestCompletionCallback callback2;
13752
13753 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
13754 rv = callback2.GetResult(rv);
13755 EXPECT_EQ(OK, rv);
13756
13757 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213758 ASSERT_TRUE(response2);
13759 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1413760 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13761
13762 std::string response_data2;
13763 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
13764 EXPECT_EQ("another", response_data2);
13765}
13766
bnc5452e2a2015-05-08 16:27:4213767// Alternative service requires HTTP/2 (or SPDY), but there is already a
13768// HTTP/1.1 socket open to the alternative server. That socket should not be
13769// used.
13770TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4613771 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4213772 HostPortPair alternative("alternative.example.org", 443);
13773 std::string origin_url = "https://origin.example.org:443";
13774 std::string alternative_url = "https://alternative.example.org:443";
13775
13776 // Negotiate HTTP/1.1 with alternative.example.org.
13777 SSLSocketDataProvider ssl(ASYNC, OK);
13778 ssl.SetNextProto(kProtoHTTP11);
13779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13780
13781 // HTTP/1.1 data for |request1| and |request2|.
13782 MockWrite http_writes[] = {
13783 MockWrite(
13784 "GET / HTTP/1.1\r\n"
13785 "Host: alternative.example.org\r\n"
13786 "Connection: keep-alive\r\n\r\n"),
13787 MockWrite(
13788 "GET / HTTP/1.1\r\n"
13789 "Host: alternative.example.org\r\n"
13790 "Connection: keep-alive\r\n\r\n"),
13791 };
13792
13793 MockRead http_reads[] = {
13794 MockRead(
13795 "HTTP/1.1 200 OK\r\n"
13796 "Content-Type: text/html; charset=iso-8859-1\r\n"
13797 "Content-Length: 40\r\n\r\n"
13798 "first HTTP/1.1 response from alternative"),
13799 MockRead(
13800 "HTTP/1.1 200 OK\r\n"
13801 "Content-Type: text/html; charset=iso-8859-1\r\n"
13802 "Content-Length: 41\r\n\r\n"
13803 "second HTTP/1.1 response from alternative"),
13804 };
13805 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13806 http_writes, arraysize(http_writes));
13807 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13808
13809 // This test documents that an alternate Job should not pool to an already
13810 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4613811 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4213812 StaticSocketDataProvider data_refused;
13813 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13814 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13815
zhongyi3d4a55e72016-04-22 20:36:4613816 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613817 session_deps_.enable_alternative_service_with_different_host = false;
danakj1fd259a02016-04-16 03:17:0913818 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213819 base::WeakPtr<HttpServerProperties> http_server_properties =
13820 session->http_server_properties();
13821 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813822 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213823 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613824 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013825 expiration);
bnc5452e2a2015-05-08 16:27:4213826
13827 // First transaction to alternative to open an HTTP/1.1 socket.
danakj1fd259a02016-04-16 03:17:0913828 std::unique_ptr<HttpTransaction> trans1(
bnc5452e2a2015-05-08 16:27:4213829 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13830 HttpRequestInfo request1;
13831 request1.method = "GET";
13832 request1.url = GURL(alternative_url);
13833 request1.load_flags = 0;
13834 TestCompletionCallback callback1;
13835
13836 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13837 EXPECT_EQ(OK, callback1.GetResult(rv));
13838 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13839 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5213840 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4213841 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13842 EXPECT_TRUE(response1->was_npn_negotiated);
13843 EXPECT_FALSE(response1->was_fetched_via_spdy);
13844 std::string response_data1;
13845 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
13846 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
13847
13848 // Request for origin.example.org, which has an alternative service. This
13849 // will start two Jobs: the alternative looks for connections to pool to,
13850 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4613851 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4213852 // this request fails.
danakj1fd259a02016-04-16 03:17:0913853 std::unique_ptr<HttpTransaction> trans2(
bnc5452e2a2015-05-08 16:27:4213854 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13855 HttpRequestInfo request2;
13856 request2.method = "GET";
13857 request2.url = GURL(origin_url);
13858 request2.load_flags = 0;
13859 TestCompletionCallback callback2;
13860
13861 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
13862 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
13863
13864 // Another transaction to alternative. This is to test that the HTTP/1.1
13865 // socket is still open and in the pool.
danakj1fd259a02016-04-16 03:17:0913866 std::unique_ptr<HttpTransaction> trans3(
bnc5452e2a2015-05-08 16:27:4213867 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13868 HttpRequestInfo request3;
13869 request3.method = "GET";
13870 request3.url = GURL(alternative_url);
13871 request3.load_flags = 0;
13872 TestCompletionCallback callback3;
13873
13874 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
13875 EXPECT_EQ(OK, callback3.GetResult(rv));
13876 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
13877 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5213878 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4213879 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
13880 EXPECT_TRUE(response3->was_npn_negotiated);
13881 EXPECT_FALSE(response3->was_fetched_via_spdy);
13882 std::string response_data3;
13883 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
13884 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
13885}
13886
[email protected]23e482282013-06-14 16:08:0213887TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2313888 const std::string https_url = "https://www.example.org:8080/";
13889 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413890
rdsmithebb50aa2015-11-12 03:44:3813891 // Separate SPDY util instance for naked and wrapped requests.
13892 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
13893
[email protected]8450d722012-07-02 19:14:0413894 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2313895 const HostPortPair host_port_pair("www.example.org", 8080);
danakj1fd259a02016-04-16 03:17:0913896 std::unique_ptr<SpdySerializedFrame> connect(
lgarrona91df87f2014-12-05 00:51:3413897 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
danakj1fd259a02016-04-16 03:17:0913898 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913899 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
danakj1fd259a02016-04-16 03:17:0913900 std::unique_ptr<SpdySerializedFrame> wrapped_req1(
[email protected]23e482282013-06-14 16:08:0213901 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3913902
13903 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2913904 SpdyHeaderBlock req2_block;
bnc7ecc1122015-09-28 13:22:4913905 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]745aa9c2014-06-27 02:21:2913906 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2313907 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2913908 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4913909 req2_block[spdy_util_.GetPathKey()] = "/";
danakj1fd259a02016-04-16 03:17:0913910 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913911 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0413912
13913 MockWrite writes1[] = {
mmenke666a6fea2015-12-19 04:16:3313914 CreateMockWrite(*connect, 0), CreateMockWrite(*wrapped_req1, 2),
13915 CreateMockWrite(*req2, 6),
[email protected]8450d722012-07-02 19:14:0413916 };
13917
danakj1fd259a02016-04-16 03:17:0913918 std::unique_ptr<SpdySerializedFrame> conn_resp(
bnc38dcd392016-02-09 23:19:4913919 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0913920 std::unique_ptr<SpdySerializedFrame> resp1(
bnc38dcd392016-02-09 23:19:4913921 spdy_util_wrapped.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0913922 std::unique_ptr<SpdySerializedFrame> body1(
bnc38dcd392016-02-09 23:19:4913923 spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913924 std::unique_ptr<SpdySerializedFrame> wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3813925 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
danakj1fd259a02016-04-16 03:17:0913926 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3813927 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
danakj1fd259a02016-04-16 03:17:0913928 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5513929 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913930 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5513931 spdy_util_.ConstructSpdyBodyFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3313932 MockRead reads1[] = {
13933 CreateMockRead(*conn_resp, 1),
13934 MockRead(ASYNC, ERR_IO_PENDING, 3),
13935 CreateMockRead(*wrapped_resp1, 4),
13936 CreateMockRead(*wrapped_body1, 5),
13937 MockRead(ASYNC, ERR_IO_PENDING, 7),
13938 CreateMockRead(*resp2, 8),
13939 CreateMockRead(*body2, 9),
13940 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
13941 };
[email protected]8450d722012-07-02 19:14:0413942
mmenke666a6fea2015-12-19 04:16:3313943 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13944 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413945 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713946 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413947
rdsmith82957ad2015-09-16 19:42:0313948 session_deps_.proxy_service =
13949 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5113950 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713951 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0413952 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3813953 ssl1.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313954 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0413955 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3813956 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313957 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13958 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0413959
danakj1fd259a02016-04-16 03:17:0913960 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0413961
13962 // Start the first transaction to set up the SpdySession
13963 HttpRequestInfo request1;
13964 request1.method = "GET";
13965 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413966 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013967 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413968 TestCompletionCallback callback1;
mmenke666a6fea2015-12-19 04:16:3313969 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0413970
mmenke666a6fea2015-12-19 04:16:3313971 // This pause is a hack to avoid running into https://crbug.com/497228.
13972 data1.RunUntilPaused();
13973 base::RunLoop().RunUntilIdle();
13974 data1.Resume();
13975 EXPECT_EQ(OK, callback1.GetResult(rv));
[email protected]8450d722012-07-02 19:14:0413976 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13977
[email protected]f6c63db52013-02-02 00:35:2213978 LoadTimingInfo load_timing_info1;
13979 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
13980 TestLoadTimingNotReusedWithPac(load_timing_info1,
13981 CONNECT_TIMING_HAS_SSL_TIMES);
13982
mmenke666a6fea2015-12-19 04:16:3313983 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0413984 HttpRequestInfo request2;
13985 request2.method = "GET";
13986 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413987 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013988 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413989 TestCompletionCallback callback2;
mmenke666a6fea2015-12-19 04:16:3313990 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0413991
mmenke666a6fea2015-12-19 04:16:3313992 // This pause is a hack to avoid running into https://crbug.com/497228.
13993 data1.RunUntilPaused();
13994 base::RunLoop().RunUntilIdle();
13995 data1.Resume();
13996 EXPECT_EQ(OK, callback2.GetResult(rv));
13997
[email protected]8450d722012-07-02 19:14:0413998 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2213999
14000 LoadTimingInfo load_timing_info2;
14001 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14002 // The established SPDY sessions is considered reused by the HTTP request.
14003 TestLoadTimingReusedWithPac(load_timing_info2);
14004 // HTTP requests over a SPDY session should have a different connection
14005 // socket_log_id than requests over a tunnel.
14006 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414007}
14008
[email protected]2d88e7d2012-07-19 17:55:1714009// Test that in the case where we have a SPDY session to a SPDY proxy
14010// that we do not pool other origins that resolve to the same IP when
14011// the certificate does not match the new origin.
14012// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0214013TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314014 const std::string url1 = "http://www.example.org/";
14015 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714016 const std::string ip_addr = "1.2.3.4";
14017
rdsmithebb50aa2015-11-12 03:44:3814018 // Second SpdyTestUtil instance for the second socket.
14019 SpdyTestUtil spdy_util_secure(GetProtocol(), GetDependenciesFromPriority());
14020
[email protected]2d88e7d2012-07-19 17:55:1714021 // SPDY GET for HTTP URL (through SPDY proxy)
danakj1fd259a02016-04-16 03:17:0914022 std::unique_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2314023 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
danakj1fd259a02016-04-16 03:17:0914024 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4914025 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714026
14027 MockWrite writes1[] = {
14028 CreateMockWrite(*req1, 0),
14029 };
14030
danakj1fd259a02016-04-16 03:17:0914031 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5514032 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914033 std::unique_ptr<SpdySerializedFrame> body1(
bncb03b1092016-04-06 11:19:5514034 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714035 MockRead reads1[] = {
mmenke666a6fea2015-12-19 04:16:3314036 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*resp1, 2),
14037 CreateMockRead(*body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714038 };
14039
mmenke666a6fea2015-12-19 04:16:3314040 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14041 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214042 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914043 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714044 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14045 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314046 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714047
14048 // SPDY GET for HTTPS URL (direct)
danakj1fd259a02016-04-16 03:17:0914049 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4914050 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714051
14052 MockWrite writes2[] = {
14053 CreateMockWrite(*req2, 0),
14054 };
14055
danakj1fd259a02016-04-16 03:17:0914056 std::unique_ptr<SpdySerializedFrame> resp2(
rdsmithebb50aa2015-11-12 03:44:3814057 spdy_util_secure.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914058 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5514059 spdy_util_secure.ConstructSpdyBodyFrame(1, true));
mmenke666a6fea2015-12-19 04:16:3314060 MockRead reads2[] = {CreateMockRead(*resp2, 1), CreateMockRead(*body2, 2),
14061 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714062
mmenke666a6fea2015-12-19 04:16:3314063 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14064 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714065 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314066 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714067
14068 // Set up a proxy config that sends HTTP requests to a proxy, and
14069 // all others direct.
14070 ProxyConfig proxy_config;
14071 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0714072 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0914073 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0414074 NULL));
[email protected]2d88e7d2012-07-19 17:55:1714075
bncce36dca22015-04-21 22:11:2314076 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3814077 ssl1.SetNextProto(GetProtocol());
[email protected]2d88e7d2012-07-19 17:55:1714078 // Load a valid cert. Note, that this does not need to
14079 // be valid for proxy because the MockSSLClientSocket does
14080 // not actually verify it. But SpdySession will use this
14081 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314082 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214083 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314084 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14085 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714086
14087 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3814088 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3314089 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14090 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714091
[email protected]bb88e1d32013-05-03 23:11:0714092 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2314093 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714094 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714095
danakj1fd259a02016-04-16 03:17:0914096 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714097
14098 // Start the first transaction to set up the SpdySession
14099 HttpRequestInfo request1;
14100 request1.method = "GET";
14101 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714102 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014103 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714104 TestCompletionCallback callback1;
14105 ASSERT_EQ(ERR_IO_PENDING,
14106 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
mmenke666a6fea2015-12-19 04:16:3314107 // This pause is a hack to avoid running into https://crbug.com/497228.
14108 data1.RunUntilPaused();
14109 base::RunLoop().RunUntilIdle();
14110 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714111
[email protected]2d88e7d2012-07-19 17:55:1714112 EXPECT_EQ(OK, callback1.WaitForResult());
14113 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14114
14115 // Now, start the HTTP request
14116 HttpRequestInfo request2;
14117 request2.method = "GET";
14118 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714119 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014120 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714121 TestCompletionCallback callback2;
14122 EXPECT_EQ(ERR_IO_PENDING,
14123 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5514124 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714125
14126 ASSERT_TRUE(callback2.have_result());
14127 EXPECT_EQ(OK, callback2.WaitForResult());
14128 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14129}
14130
[email protected]85f97342013-04-17 06:12:2414131// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14132// error) in SPDY session, removes the socket from pool and closes the SPDY
14133// session. Verify that new url's from the same HttpNetworkSession (and a new
14134// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0214135TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314136 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414137
14138 MockRead reads1[] = {
14139 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14140 };
14141
mmenke11eb5152015-06-09 14:50:5014142 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414143
danakj1fd259a02016-04-16 03:17:0914144 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4914145 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414146 MockWrite writes2[] = {
14147 CreateMockWrite(*req2, 0),
14148 };
14149
danakj1fd259a02016-04-16 03:17:0914150 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5514151 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914152 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5514153 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414154 MockRead reads2[] = {
14155 CreateMockRead(*resp2, 1),
14156 CreateMockRead(*body2, 2),
14157 MockRead(ASYNC, OK, 3) // EOF
14158 };
14159
mmenke11eb5152015-06-09 14:50:5014160 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14161 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414162
[email protected]85f97342013-04-17 06:12:2414163 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814164 ssl1.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5014165 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14166 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414167
14168 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814169 ssl2.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5014170 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14171 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414172
danakj1fd259a02016-04-16 03:17:0914173 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014174 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414175
14176 // Start the first transaction to set up the SpdySession and verify that
14177 // connection was closed.
14178 HttpRequestInfo request1;
14179 request1.method = "GET";
14180 request1.url = GURL(https_url);
14181 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014182 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414183 TestCompletionCallback callback1;
14184 EXPECT_EQ(ERR_IO_PENDING,
14185 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2414186 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
14187
14188 // Now, start the second request and make sure it succeeds.
14189 HttpRequestInfo request2;
14190 request2.method = "GET";
14191 request2.url = GURL(https_url);
14192 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014193 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414194 TestCompletionCallback callback2;
14195 EXPECT_EQ(ERR_IO_PENDING,
14196 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2414197
mmenke11eb5152015-06-09 14:50:5014198 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2414199 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14200}
14201
[email protected]23e482282013-06-14 16:08:0214202TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314203 ClientSocketPoolManager::set_max_sockets_per_group(
14204 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14205 ClientSocketPoolManager::set_max_sockets_per_pool(
14206 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14207
14208 // Use two different hosts with different IPs so they don't get pooled.
14209 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14210 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914211 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314212
14213 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814214 ssl1.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0314215 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814216 ssl2.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0314217 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14218 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14219
danakj1fd259a02016-04-16 03:17:0914220 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4914221 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314222 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1314223 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314224 };
danakj1fd259a02016-04-16 03:17:0914225 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0214226 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914227 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0214228 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314229 MockRead spdy1_reads[] = {
mmenkee24011922015-12-17 22:12:5914230 CreateMockRead(*host1_resp, 1), CreateMockRead(*host1_resp_body, 2),
14231 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314232 };
14233
rdsmithebb50aa2015-11-12 03:44:3814234 // Use a separate test instance for the separate SpdySession that will be
14235 // created.
14236 SpdyTestUtil spdy_util_2(GetProtocol(), GetDependenciesFromPriority());
danakj1fd259a02016-04-16 03:17:0914237 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1314238 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14239 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0314240 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14241
danakj1fd259a02016-04-16 03:17:0914242 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4914243 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314244 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1314245 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314246 };
danakj1fd259a02016-04-16 03:17:0914247 std::unique_ptr<SpdySerializedFrame> host2_resp(
rdsmithebb50aa2015-11-12 03:44:3814248 spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914249 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
rdsmithebb50aa2015-11-12 03:44:3814250 spdy_util_2.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314251 MockRead spdy2_reads[] = {
mmenkee24011922015-12-17 22:12:5914252 CreateMockRead(*host2_resp, 1), CreateMockRead(*host2_resp_body, 2),
14253 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314254 };
14255
danakj1fd259a02016-04-16 03:17:0914256 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1314257 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14258 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0314259 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14260
14261 MockWrite http_write[] = {
14262 MockWrite("GET / HTTP/1.1\r\n"
14263 "Host: www.a.com\r\n"
14264 "Connection: keep-alive\r\n\r\n"),
14265 };
14266
14267 MockRead http_read[] = {
14268 MockRead("HTTP/1.1 200 OK\r\n"),
14269 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14270 MockRead("Content-Length: 6\r\n\r\n"),
14271 MockRead("hello!"),
14272 };
14273 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14274 http_write, arraysize(http_write));
14275 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14276
14277 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014278 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314279 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314280 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614281 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314282
14283 TestCompletionCallback callback;
14284 HttpRequestInfo request1;
14285 request1.method = "GET";
14286 request1.url = GURL("https://www.a.com/");
14287 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0914288 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5014289 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314290
14291 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
14292 EXPECT_EQ(ERR_IO_PENDING, rv);
14293 EXPECT_EQ(OK, callback.WaitForResult());
14294
14295 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214296 ASSERT_TRUE(response);
14297 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214298 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314299 EXPECT_TRUE(response->was_fetched_via_spdy);
14300 EXPECT_TRUE(response->was_npn_negotiated);
14301
14302 std::string response_data;
14303 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14304 EXPECT_EQ("hello!", response_data);
14305 trans.reset();
14306 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614307 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314308
14309 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014310 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314311 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314312 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614313 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314314 HttpRequestInfo request2;
14315 request2.method = "GET";
14316 request2.url = GURL("https://www.b.com/");
14317 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014318 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314319
14320 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
14321 EXPECT_EQ(ERR_IO_PENDING, rv);
14322 EXPECT_EQ(OK, callback.WaitForResult());
14323
14324 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214325 ASSERT_TRUE(response);
14326 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214327 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314328 EXPECT_TRUE(response->was_fetched_via_spdy);
14329 EXPECT_TRUE(response->was_npn_negotiated);
14330 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14331 EXPECT_EQ("hello!", response_data);
14332 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614333 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314334 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614335 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314336
14337 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014338 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314339 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314340 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614341 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314342 HttpRequestInfo request3;
14343 request3.method = "GET";
14344 request3.url = GURL("http://www.a.com/");
14345 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014346 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314347
14348 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
14349 EXPECT_EQ(ERR_IO_PENDING, rv);
14350 EXPECT_EQ(OK, callback.WaitForResult());
14351
14352 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214353 ASSERT_TRUE(response);
14354 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314355 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14356 EXPECT_FALSE(response->was_fetched_via_spdy);
14357 EXPECT_FALSE(response->was_npn_negotiated);
14358 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14359 EXPECT_EQ("hello!", response_data);
14360 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614361 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314362 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614363 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314364}
14365
[email protected]79e1fd62013-06-20 06:50:0414366TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
14367 HttpRequestInfo request;
14368 request.method = "GET";
bncce36dca22015-04-21 22:11:2314369 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414370 request.load_flags = 0;
14371
danakj1fd259a02016-04-16 03:17:0914372 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14373 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114374 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414375
ttuttled9dbc652015-09-29 20:00:5914376 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414377 StaticSocketDataProvider data;
14378 data.set_connect_data(mock_connect);
14379 session_deps_.socket_factory->AddSocketDataProvider(&data);
14380
14381 TestCompletionCallback callback;
14382
14383 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14384 EXPECT_EQ(ERR_IO_PENDING, rv);
14385
14386 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5914387 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0414388
[email protected]79e1fd62013-06-20 06:50:0414389 // We don't care whether this succeeds or fails, but it shouldn't crash.
14390 HttpRequestHeaders request_headers;
14391 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714392
14393 ConnectionAttempts attempts;
14394 trans->GetConnectionAttempts(&attempts);
14395 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5914396 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
14397
14398 IPEndPoint endpoint;
14399 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
14400 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414401}
14402
14403TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
14404 HttpRequestInfo request;
14405 request.method = "GET";
bncce36dca22015-04-21 22:11:2314406 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414407 request.load_flags = 0;
14408
danakj1fd259a02016-04-16 03:17:0914409 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14410 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114411 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414412
ttuttled9dbc652015-09-29 20:00:5914413 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414414 StaticSocketDataProvider data;
14415 data.set_connect_data(mock_connect);
14416 session_deps_.socket_factory->AddSocketDataProvider(&data);
14417
14418 TestCompletionCallback callback;
14419
14420 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14421 EXPECT_EQ(ERR_IO_PENDING, rv);
14422
14423 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5914424 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0414425
[email protected]79e1fd62013-06-20 06:50:0414426 // We don't care whether this succeeds or fails, but it shouldn't crash.
14427 HttpRequestHeaders request_headers;
14428 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714429
14430 ConnectionAttempts attempts;
14431 trans->GetConnectionAttempts(&attempts);
14432 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5914433 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
14434
14435 IPEndPoint endpoint;
14436 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
14437 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414438}
14439
14440TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
14441 HttpRequestInfo request;
14442 request.method = "GET";
bncce36dca22015-04-21 22:11:2314443 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414444 request.load_flags = 0;
14445
danakj1fd259a02016-04-16 03:17:0914446 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14447 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114448 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414449
14450 MockWrite data_writes[] = {
14451 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14452 };
14453 MockRead data_reads[] = {
14454 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14455 };
14456
14457 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14458 data_writes, arraysize(data_writes));
14459 session_deps_.socket_factory->AddSocketDataProvider(&data);
14460
14461 TestCompletionCallback callback;
14462
14463 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14464 EXPECT_EQ(ERR_IO_PENDING, rv);
14465
14466 rv = callback.WaitForResult();
14467 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14468
[email protected]79e1fd62013-06-20 06:50:0414469 HttpRequestHeaders request_headers;
14470 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14471 EXPECT_TRUE(request_headers.HasHeader("Host"));
14472}
14473
14474TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
14475 HttpRequestInfo request;
14476 request.method = "GET";
bncce36dca22015-04-21 22:11:2314477 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414478 request.load_flags = 0;
14479
danakj1fd259a02016-04-16 03:17:0914480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14481 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114482 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414483
14484 MockWrite data_writes[] = {
14485 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14486 };
14487 MockRead data_reads[] = {
14488 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14489 };
14490
14491 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14492 data_writes, arraysize(data_writes));
14493 session_deps_.socket_factory->AddSocketDataProvider(&data);
14494
14495 TestCompletionCallback callback;
14496
14497 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14498 EXPECT_EQ(ERR_IO_PENDING, rv);
14499
14500 rv = callback.WaitForResult();
14501 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14502
[email protected]79e1fd62013-06-20 06:50:0414503 HttpRequestHeaders request_headers;
14504 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14505 EXPECT_TRUE(request_headers.HasHeader("Host"));
14506}
14507
14508TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
14509 HttpRequestInfo request;
14510 request.method = "GET";
bncce36dca22015-04-21 22:11:2314511 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414512 request.load_flags = 0;
14513
danakj1fd259a02016-04-16 03:17:0914514 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14515 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114516 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414517
14518 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314519 MockWrite(
14520 "GET / HTTP/1.1\r\n"
14521 "Host: www.example.org\r\n"
14522 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414523 };
14524 MockRead data_reads[] = {
14525 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14526 };
14527
14528 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14529 data_writes, arraysize(data_writes));
14530 session_deps_.socket_factory->AddSocketDataProvider(&data);
14531
14532 TestCompletionCallback callback;
14533
14534 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14535 EXPECT_EQ(ERR_IO_PENDING, rv);
14536
14537 rv = callback.WaitForResult();
14538 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14539
[email protected]79e1fd62013-06-20 06:50:0414540 HttpRequestHeaders request_headers;
14541 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14542 EXPECT_TRUE(request_headers.HasHeader("Host"));
14543}
14544
14545TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
14546 HttpRequestInfo request;
14547 request.method = "GET";
bncce36dca22015-04-21 22:11:2314548 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414549 request.load_flags = 0;
14550
danakj1fd259a02016-04-16 03:17:0914551 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14552 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114553 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414554
14555 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314556 MockWrite(
14557 "GET / HTTP/1.1\r\n"
14558 "Host: www.example.org\r\n"
14559 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414560 };
14561 MockRead data_reads[] = {
14562 MockRead(ASYNC, ERR_CONNECTION_RESET),
14563 };
14564
14565 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14566 data_writes, arraysize(data_writes));
14567 session_deps_.socket_factory->AddSocketDataProvider(&data);
14568
14569 TestCompletionCallback callback;
14570
14571 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14572 EXPECT_EQ(ERR_IO_PENDING, rv);
14573
14574 rv = callback.WaitForResult();
14575 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14576
[email protected]79e1fd62013-06-20 06:50:0414577 HttpRequestHeaders request_headers;
14578 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14579 EXPECT_TRUE(request_headers.HasHeader("Host"));
14580}
14581
14582TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
14583 HttpRequestInfo request;
14584 request.method = "GET";
bncce36dca22015-04-21 22:11:2314585 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414586 request.load_flags = 0;
14587 request.extra_headers.SetHeader("X-Foo", "bar");
14588
danakj1fd259a02016-04-16 03:17:0914589 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14590 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114591 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414592
14593 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314594 MockWrite(
14595 "GET / HTTP/1.1\r\n"
14596 "Host: www.example.org\r\n"
14597 "Connection: keep-alive\r\n"
14598 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414599 };
14600 MockRead data_reads[] = {
14601 MockRead("HTTP/1.1 200 OK\r\n"
14602 "Content-Length: 5\r\n\r\n"
14603 "hello"),
14604 MockRead(ASYNC, ERR_UNEXPECTED),
14605 };
14606
14607 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14608 data_writes, arraysize(data_writes));
14609 session_deps_.socket_factory->AddSocketDataProvider(&data);
14610
14611 TestCompletionCallback callback;
14612
14613 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14614 EXPECT_EQ(ERR_IO_PENDING, rv);
14615
14616 rv = callback.WaitForResult();
14617 EXPECT_EQ(OK, rv);
14618
14619 HttpRequestHeaders request_headers;
14620 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14621 std::string foo;
14622 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14623 EXPECT_EQ("bar", foo);
14624}
14625
[email protected]bf828982013-08-14 18:01:4714626namespace {
14627
yhiranoa7e05bb2014-11-06 05:40:3914628// Fake HttpStream that simply records calls to SetPriority().
14629class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314630 public base::SupportsWeakPtr<FakeStream> {
14631 public:
14632 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014633 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314634
14635 RequestPriority priority() const { return priority_; }
14636
dchengb03027d2014-10-21 12:00:2014637 int InitializeStream(const HttpRequestInfo* request_info,
14638 RequestPriority priority,
14639 const BoundNetLog& net_log,
14640 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314641 return ERR_IO_PENDING;
14642 }
14643
dchengb03027d2014-10-21 12:00:2014644 int SendRequest(const HttpRequestHeaders& request_headers,
14645 HttpResponseInfo* response,
14646 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314647 ADD_FAILURE();
14648 return ERR_UNEXPECTED;
14649 }
14650
dchengb03027d2014-10-21 12:00:2014651 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314652 ADD_FAILURE();
14653 return ERR_UNEXPECTED;
14654 }
14655
dchengb03027d2014-10-21 12:00:2014656 int ReadResponseBody(IOBuffer* buf,
14657 int buf_len,
14658 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314659 ADD_FAILURE();
14660 return ERR_UNEXPECTED;
14661 }
14662
dchengb03027d2014-10-21 12:00:2014663 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314664
dchengb03027d2014-10-21 12:00:2014665 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314666 ADD_FAILURE();
14667 return false;
14668 }
14669
dchengb03027d2014-10-21 12:00:2014670 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314671 ADD_FAILURE();
14672 return false;
14673 }
14674
dchengb03027d2014-10-21 12:00:2014675 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314676
mmenkebd84c392015-09-02 14:12:3414677 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314678
sclittle4de1bab92015-09-22 21:28:2414679 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914680 ADD_FAILURE();
14681 return 0;
14682 }
14683
sclittlebe1ccf62015-09-02 19:40:3614684 int64_t GetTotalSentBytes() const override {
14685 ADD_FAILURE();
14686 return 0;
14687 }
14688
dchengb03027d2014-10-21 12:00:2014689 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314690 ADD_FAILURE();
14691 return false;
14692 }
14693
dchengb03027d2014-10-21 12:00:2014694 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14695
14696 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314697 ADD_FAILURE();
14698 }
14699
ttuttled9dbc652015-09-29 20:00:5914700 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14701
nharperb7441ef2016-01-25 23:54:1414702 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14703 std::vector<uint8_t>* out) override {
14704 ADD_FAILURE();
14705 return ERR_NOT_IMPLEMENTED;
14706 }
14707
dchengb03027d2014-10-21 12:00:2014708 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314709
zhongyica364fbb2015-12-12 03:39:1214710 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14711
dchengb03027d2014-10-21 12:00:2014712 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314713
yhiranoa7e05bb2014-11-06 05:40:3914714 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
14715
14716 HttpStream* RenewStreamForAuth() override { return NULL; }
14717
[email protected]e86839fd2013-08-14 18:29:0314718 private:
14719 RequestPriority priority_;
14720
14721 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14722};
14723
14724// Fake HttpStreamRequest that simply records calls to SetPriority()
14725// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714726class FakeStreamRequest : public HttpStreamRequest,
14727 public base::SupportsWeakPtr<FakeStreamRequest> {
14728 public:
[email protected]e86839fd2013-08-14 18:29:0314729 FakeStreamRequest(RequestPriority priority,
14730 HttpStreamRequest::Delegate* delegate)
14731 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414732 delegate_(delegate),
14733 websocket_stream_create_helper_(NULL) {}
14734
14735 FakeStreamRequest(RequestPriority priority,
14736 HttpStreamRequest::Delegate* delegate,
14737 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14738 : priority_(priority),
14739 delegate_(delegate),
14740 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314741
dchengb03027d2014-10-21 12:00:2014742 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714743
14744 RequestPriority priority() const { return priority_; }
14745
[email protected]831e4a32013-11-14 02:14:4414746 const WebSocketHandshakeStreamBase::CreateHelper*
14747 websocket_stream_create_helper() const {
14748 return websocket_stream_create_helper_;
14749 }
14750
[email protected]e86839fd2013-08-14 18:29:0314751 // Create a new FakeStream and pass it to the request's
14752 // delegate. Returns a weak pointer to the FakeStream.
14753 base::WeakPtr<FakeStream> FinishStreamRequest() {
14754 FakeStream* fake_stream = new FakeStream(priority_);
14755 // Do this before calling OnStreamReady() as OnStreamReady() may
14756 // immediately delete |fake_stream|.
14757 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14758 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14759 return weak_stream;
14760 }
14761
dchengb03027d2014-10-21 12:00:2014762 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714763 ADD_FAILURE();
14764 return ERR_UNEXPECTED;
14765 }
14766
dchengb03027d2014-10-21 12:00:2014767 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714768 ADD_FAILURE();
14769 return LoadState();
14770 }
14771
dchengb03027d2014-10-21 12:00:2014772 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714773
dchengb03027d2014-10-21 12:00:2014774 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714775
dchengb03027d2014-10-21 12:00:2014776 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714777
dchengb03027d2014-10-21 12:00:2014778 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714779
ttuttle1f2d7e92015-04-28 16:17:4714780 const ConnectionAttempts& connection_attempts() const override {
14781 static ConnectionAttempts no_attempts;
14782 return no_attempts;
14783 }
14784
[email protected]bf828982013-08-14 18:01:4714785 private:
14786 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314787 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414788 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714789
14790 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14791};
14792
14793// Fake HttpStreamFactory that vends FakeStreamRequests.
14794class FakeStreamFactory : public HttpStreamFactory {
14795 public:
14796 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014797 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714798
14799 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14800 // RequestStream() (which may be NULL if it was destroyed already).
14801 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14802 return last_stream_request_;
14803 }
14804
dchengb03027d2014-10-21 12:00:2014805 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14806 RequestPriority priority,
14807 const SSLConfig& server_ssl_config,
14808 const SSLConfig& proxy_ssl_config,
14809 HttpStreamRequest::Delegate* delegate,
14810 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314811 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714812 last_stream_request_ = fake_request->AsWeakPtr();
14813 return fake_request;
14814 }
14815
xunjieli5749218c2016-03-22 16:43:0614816 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0814817 const HttpRequestInfo& info,
14818 RequestPriority priority,
14819 const SSLConfig& server_ssl_config,
14820 const SSLConfig& proxy_ssl_config,
14821 HttpStreamRequest::Delegate* delegate,
14822 const BoundNetLog& net_log) override {
14823 NOTREACHED();
14824 return nullptr;
14825 }
14826
dchengb03027d2014-10-21 12:00:2014827 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714828 const HttpRequestInfo& info,
14829 RequestPriority priority,
14830 const SSLConfig& server_ssl_config,
14831 const SSLConfig& proxy_ssl_config,
14832 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614833 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1314834 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414835 FakeStreamRequest* fake_request =
14836 new FakeStreamRequest(priority, delegate, create_helper);
14837 last_stream_request_ = fake_request->AsWeakPtr();
14838 return fake_request;
[email protected]bf828982013-08-14 18:01:4714839 }
14840
dchengb03027d2014-10-21 12:00:2014841 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5914842 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4714843 ADD_FAILURE();
14844 }
14845
dchengb03027d2014-10-21 12:00:2014846 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714847 ADD_FAILURE();
14848 return NULL;
14849 }
14850
14851 private:
14852 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14853
14854 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14855};
14856
Adam Rice425cf122015-01-19 06:18:2414857// TODO(ricea): Maybe unify this with the one in
14858// url_request_http_job_unittest.cc ?
14859class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14860 public:
danakj1fd259a02016-04-16 03:17:0914861 FakeWebSocketBasicHandshakeStream(
14862 std::unique_ptr<ClientSocketHandle> connection,
14863 bool using_proxy)
Adam Rice425cf122015-01-19 06:18:2414864 : state_(connection.release(), using_proxy) {}
14865
14866 // Fake implementation of HttpStreamBase methods.
14867 // This ends up being quite "real" because this object has to really send data
14868 // on the mock socket. It might be easier to use the real implementation, but
14869 // the fact that the WebSocket code is not compiled on iOS makes that
14870 // difficult.
14871 int InitializeStream(const HttpRequestInfo* request_info,
14872 RequestPriority priority,
14873 const BoundNetLog& net_log,
14874 const CompletionCallback& callback) override {
14875 state_.Initialize(request_info, priority, net_log, callback);
14876 return OK;
14877 }
14878
14879 int SendRequest(const HttpRequestHeaders& request_headers,
14880 HttpResponseInfo* response,
14881 const CompletionCallback& callback) override {
14882 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
14883 response, callback);
14884 }
14885
14886 int ReadResponseHeaders(const CompletionCallback& callback) override {
14887 return parser()->ReadResponseHeaders(callback);
14888 }
14889
14890 int ReadResponseBody(IOBuffer* buf,
14891 int buf_len,
14892 const CompletionCallback& callback) override {
14893 NOTREACHED();
14894 return ERR_IO_PENDING;
14895 }
14896
14897 void Close(bool not_reusable) override {
14898 if (parser())
14899 parser()->Close(true);
14900 }
14901
14902 bool IsResponseBodyComplete() const override {
14903 NOTREACHED();
14904 return false;
14905 }
14906
Adam Rice425cf122015-01-19 06:18:2414907 bool IsConnectionReused() const override {
14908 NOTREACHED();
14909 return false;
14910 }
14911 void SetConnectionReused() override { NOTREACHED(); }
14912
mmenkebd84c392015-09-02 14:12:3414913 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2414914
sclittle4de1bab92015-09-22 21:28:2414915 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2414916 NOTREACHED();
14917 return 0;
14918 }
14919
sclittlebe1ccf62015-09-02 19:40:3614920 int64_t GetTotalSentBytes() const override {
14921 NOTREACHED();
14922 return 0;
14923 }
14924
Adam Rice425cf122015-01-19 06:18:2414925 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
14926 NOTREACHED();
14927 return false;
14928 }
14929
Adam Ricecb76ac62015-02-20 05:33:2514930 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2414931
14932 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
14933 NOTREACHED();
14934 }
14935
ttuttled9dbc652015-09-29 20:00:5914936 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14937
nharperb7441ef2016-01-25 23:54:1414938 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14939 std::vector<uint8_t>* out) override {
14940 ADD_FAILURE();
14941 return ERR_NOT_IMPLEMENTED;
14942 }
14943
Adam Rice425cf122015-01-19 06:18:2414944 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
14945
zhongyica364fbb2015-12-12 03:39:1214946 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14947
Adam Rice425cf122015-01-19 06:18:2414948 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
14949
14950 UploadProgress GetUploadProgress() const override {
14951 NOTREACHED();
14952 return UploadProgress();
14953 }
14954
14955 HttpStream* RenewStreamForAuth() override {
14956 NOTREACHED();
14957 return nullptr;
14958 }
14959
14960 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0914961 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2414962 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0914963 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2414964 }
14965
14966 private:
14967 HttpStreamParser* parser() const { return state_.parser(); }
14968 HttpBasicState state_;
14969
14970 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
14971};
14972
[email protected]831e4a32013-11-14 02:14:4414973// TODO(yhirano): Split this class out into a net/websockets file, if it is
14974// worth doing.
14975class FakeWebSocketStreamCreateHelper :
14976 public WebSocketHandshakeStreamBase::CreateHelper {
14977 public:
dchengb03027d2014-10-21 12:00:2014978 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0914979 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1314980 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4814981 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2414982 using_proxy);
[email protected]831e4a32013-11-14 02:14:4414983 }
14984
dchengb03027d2014-10-21 12:00:2014985 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4414986 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1314987 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4414988 NOTREACHED();
14989 return NULL;
14990 };
14991
dchengb03027d2014-10-21 12:00:2014992 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4414993
danakj1fd259a02016-04-16 03:17:0914994 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4414995 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0914996 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4414997 }
14998};
14999
[email protected]bf828982013-08-14 18:01:4715000} // namespace
15001
15002// Make sure that HttpNetworkTransaction passes on its priority to its
15003// stream request on start.
15004TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915005 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215006 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715007 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915008 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715009
dcheng48459ac22014-08-26 00:46:4115010 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715011
wezca1070932016-05-26 20:30:5215012 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715013
15014 HttpRequestInfo request;
15015 TestCompletionCallback callback;
15016 EXPECT_EQ(ERR_IO_PENDING,
15017 trans.Start(&request, callback.callback(), BoundNetLog()));
15018
15019 base::WeakPtr<FakeStreamRequest> fake_request =
15020 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215021 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715022 EXPECT_EQ(LOW, fake_request->priority());
15023}
15024
15025// Make sure that HttpNetworkTransaction passes on its priority
15026// updates to its stream request.
15027TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915028 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215029 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715030 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915031 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715032
dcheng48459ac22014-08-26 00:46:4115033 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715034
15035 HttpRequestInfo request;
15036 TestCompletionCallback callback;
15037 EXPECT_EQ(ERR_IO_PENDING,
15038 trans.Start(&request, callback.callback(), BoundNetLog()));
15039
15040 base::WeakPtr<FakeStreamRequest> fake_request =
15041 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215042 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715043 EXPECT_EQ(LOW, fake_request->priority());
15044
15045 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215046 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715047 EXPECT_EQ(LOWEST, fake_request->priority());
15048}
15049
[email protected]e86839fd2013-08-14 18:29:0315050// Make sure that HttpNetworkTransaction passes on its priority
15051// updates to its stream.
15052TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915053 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215054 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315055 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915056 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315057
dcheng48459ac22014-08-26 00:46:4115058 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315059
15060 HttpRequestInfo request;
15061 TestCompletionCallback callback;
15062 EXPECT_EQ(ERR_IO_PENDING,
15063 trans.Start(&request, callback.callback(), BoundNetLog()));
15064
15065 base::WeakPtr<FakeStreamRequest> fake_request =
15066 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215067 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315068 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215069 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315070 EXPECT_EQ(LOW, fake_stream->priority());
15071
15072 trans.SetPriority(LOWEST);
15073 EXPECT_EQ(LOWEST, fake_stream->priority());
15074}
15075
[email protected]831e4a32013-11-14 02:14:4415076TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
15077 // The same logic needs to be tested for both ws: and wss: schemes, but this
15078 // test is already parameterised on NextProto, so it uses a loop to verify
15079 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315080 std::string test_cases[] = {"ws://www.example.org/",
15081 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415082 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915083 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215084 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415085 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15086 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315087 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915088 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415089
dcheng48459ac22014-08-26 00:46:4115090 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415091 trans.SetWebSocketHandshakeStreamCreateHelper(
15092 &websocket_stream_create_helper);
15093
15094 HttpRequestInfo request;
15095 TestCompletionCallback callback;
15096 request.method = "GET";
15097 request.url = GURL(test_cases[i]);
15098
15099 EXPECT_EQ(ERR_IO_PENDING,
15100 trans.Start(&request, callback.callback(), BoundNetLog()));
15101
15102 base::WeakPtr<FakeStreamRequest> fake_request =
15103 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215104 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415105 EXPECT_EQ(&websocket_stream_create_helper,
15106 fake_request->websocket_stream_create_helper());
15107 }
15108}
15109
[email protected]043b68c82013-08-22 23:41:5215110// Tests that when a used socket is returned to the SSL socket pool, it's closed
15111// if the transport socket pool is stalled on the global socket limit.
15112TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
15113 ClientSocketPoolManager::set_max_sockets_per_group(
15114 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15115 ClientSocketPoolManager::set_max_sockets_per_pool(
15116 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15117
15118 // Set up SSL request.
15119
15120 HttpRequestInfo ssl_request;
15121 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315122 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215123
15124 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315125 MockWrite(
15126 "GET / HTTP/1.1\r\n"
15127 "Host: www.example.org\r\n"
15128 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215129 };
15130 MockRead ssl_reads[] = {
15131 MockRead("HTTP/1.1 200 OK\r\n"),
15132 MockRead("Content-Length: 11\r\n\r\n"),
15133 MockRead("hello world"),
15134 MockRead(SYNCHRONOUS, OK),
15135 };
15136 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15137 ssl_writes, arraysize(ssl_writes));
15138 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15139
15140 SSLSocketDataProvider ssl(ASYNC, OK);
15141 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15142
15143 // Set up HTTP request.
15144
15145 HttpRequestInfo http_request;
15146 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315147 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215148
15149 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315150 MockWrite(
15151 "GET / HTTP/1.1\r\n"
15152 "Host: www.example.org\r\n"
15153 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215154 };
15155 MockRead http_reads[] = {
15156 MockRead("HTTP/1.1 200 OK\r\n"),
15157 MockRead("Content-Length: 7\r\n\r\n"),
15158 MockRead("falafel"),
15159 MockRead(SYNCHRONOUS, OK),
15160 };
15161 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15162 http_writes, arraysize(http_writes));
15163 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15164
danakj1fd259a02016-04-16 03:17:0915165 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215166
15167 // Start the SSL request.
15168 TestCompletionCallback ssl_callback;
danakj1fd259a02016-04-16 03:17:0915169 std::unique_ptr<HttpTransaction> ssl_trans(
[email protected]043b68c82013-08-22 23:41:5215170 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15171 ASSERT_EQ(ERR_IO_PENDING,
15172 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
15173 BoundNetLog()));
15174
15175 // Start the HTTP request. Pool should stall.
15176 TestCompletionCallback http_callback;
danakj1fd259a02016-04-16 03:17:0915177 std::unique_ptr<HttpTransaction> http_trans(
[email protected]043b68c82013-08-22 23:41:5215178 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15179 ASSERT_EQ(ERR_IO_PENDING,
15180 http_trans->Start(&http_request, http_callback.callback(),
15181 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4115182 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215183
15184 // Wait for response from SSL request.
15185 ASSERT_EQ(OK, ssl_callback.WaitForResult());
15186 std::string response_data;
15187 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
15188 EXPECT_EQ("hello world", response_data);
15189
15190 // The SSL socket should automatically be closed, so the HTTP request can
15191 // start.
dcheng48459ac22014-08-26 00:46:4115192 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15193 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215194
15195 // The HTTP request can now complete.
15196 ASSERT_EQ(OK, http_callback.WaitForResult());
15197 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
15198 EXPECT_EQ("falafel", response_data);
15199
dcheng48459ac22014-08-26 00:46:4115200 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215201}
15202
15203// Tests that when a SSL connection is established but there's no corresponding
15204// request that needs it, the new socket is closed if the transport socket pool
15205// is stalled on the global socket limit.
15206TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
15207 ClientSocketPoolManager::set_max_sockets_per_group(
15208 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15209 ClientSocketPoolManager::set_max_sockets_per_pool(
15210 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15211
15212 // Set up an ssl request.
15213
15214 HttpRequestInfo ssl_request;
15215 ssl_request.method = "GET";
15216 ssl_request.url = GURL("https://www.foopy.com/");
15217
15218 // No data will be sent on the SSL socket.
15219 StaticSocketDataProvider ssl_data;
15220 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15221
15222 SSLSocketDataProvider ssl(ASYNC, OK);
15223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15224
15225 // Set up HTTP request.
15226
15227 HttpRequestInfo http_request;
15228 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315229 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215230
15231 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315232 MockWrite(
15233 "GET / HTTP/1.1\r\n"
15234 "Host: www.example.org\r\n"
15235 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215236 };
15237 MockRead http_reads[] = {
15238 MockRead("HTTP/1.1 200 OK\r\n"),
15239 MockRead("Content-Length: 7\r\n\r\n"),
15240 MockRead("falafel"),
15241 MockRead(SYNCHRONOUS, OK),
15242 };
15243 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15244 http_writes, arraysize(http_writes));
15245 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15246
danakj1fd259a02016-04-16 03:17:0915247 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215248
15249 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15250 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915251 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915252 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115253 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215254
15255 // Start the HTTP request. Pool should stall.
15256 TestCompletionCallback http_callback;
danakj1fd259a02016-04-16 03:17:0915257 std::unique_ptr<HttpTransaction> http_trans(
[email protected]043b68c82013-08-22 23:41:5215258 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15259 ASSERT_EQ(ERR_IO_PENDING,
15260 http_trans->Start(&http_request, http_callback.callback(),
15261 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4115262 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215263
15264 // The SSL connection will automatically be closed once the connection is
15265 // established, to let the HTTP request start.
15266 ASSERT_EQ(OK, http_callback.WaitForResult());
15267 std::string response_data;
15268 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
15269 EXPECT_EQ("falafel", response_data);
15270
dcheng48459ac22014-08-26 00:46:4115271 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215272}
15273
[email protected]02d74a02014-04-23 18:10:5415274TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915275 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215276 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915277 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215278 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415279
15280 HttpRequestInfo request;
15281 request.method = "POST";
15282 request.url = GURL("http://www.foo.com/");
15283 request.upload_data_stream = &upload_data_stream;
15284 request.load_flags = 0;
15285
danakj1fd259a02016-04-16 03:17:0915286 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15287 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115288 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415289 // Send headers successfully, but get an error while sending the body.
15290 MockWrite data_writes[] = {
15291 MockWrite("POST / HTTP/1.1\r\n"
15292 "Host: www.foo.com\r\n"
15293 "Connection: keep-alive\r\n"
15294 "Content-Length: 3\r\n\r\n"),
15295 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15296 };
15297
15298 MockRead data_reads[] = {
15299 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15300 MockRead("hello world"),
15301 MockRead(SYNCHRONOUS, OK),
15302 };
15303 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15304 arraysize(data_writes));
15305 session_deps_.socket_factory->AddSocketDataProvider(&data);
15306
15307 TestCompletionCallback callback;
15308
15309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15310 EXPECT_EQ(ERR_IO_PENDING, rv);
15311
15312 rv = callback.WaitForResult();
15313 EXPECT_EQ(OK, rv);
15314
15315 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215316 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415317
wezca1070932016-05-26 20:30:5215318 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415319 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15320
15321 std::string response_data;
15322 rv = ReadTransaction(trans.get(), &response_data);
15323 EXPECT_EQ(OK, rv);
15324 EXPECT_EQ("hello world", response_data);
15325}
15326
15327// This test makes sure the retry logic doesn't trigger when reading an error
15328// response from a server that rejected a POST with a CONNECTION_RESET.
15329TEST_P(HttpNetworkTransactionTest,
15330 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915331 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415332 MockWrite data_writes[] = {
15333 MockWrite("GET / HTTP/1.1\r\n"
15334 "Host: www.foo.com\r\n"
15335 "Connection: keep-alive\r\n\r\n"),
15336 MockWrite("POST / HTTP/1.1\r\n"
15337 "Host: www.foo.com\r\n"
15338 "Connection: keep-alive\r\n"
15339 "Content-Length: 3\r\n\r\n"),
15340 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15341 };
15342
15343 MockRead data_reads[] = {
15344 MockRead("HTTP/1.1 200 Peachy\r\n"
15345 "Content-Length: 14\r\n\r\n"),
15346 MockRead("first response"),
15347 MockRead("HTTP/1.1 400 Not OK\r\n"
15348 "Content-Length: 15\r\n\r\n"),
15349 MockRead("second response"),
15350 MockRead(SYNCHRONOUS, OK),
15351 };
15352 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15353 arraysize(data_writes));
15354 session_deps_.socket_factory->AddSocketDataProvider(&data);
15355
15356 TestCompletionCallback callback;
15357 HttpRequestInfo request1;
15358 request1.method = "GET";
15359 request1.url = GURL("http://www.foo.com/");
15360 request1.load_flags = 0;
15361
danakj1fd259a02016-04-16 03:17:0915362 std::unique_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4115363 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415364 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
15365 EXPECT_EQ(ERR_IO_PENDING, rv);
15366
15367 rv = callback.WaitForResult();
15368 EXPECT_EQ(OK, rv);
15369
15370 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215371 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415372
wezca1070932016-05-26 20:30:5215373 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415374 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15375
15376 std::string response_data1;
15377 rv = ReadTransaction(trans1.get(), &response_data1);
15378 EXPECT_EQ(OK, rv);
15379 EXPECT_EQ("first response", response_data1);
15380 // Delete the transaction to release the socket back into the socket pool.
15381 trans1.reset();
15382
danakj1fd259a02016-04-16 03:17:0915383 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215384 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915385 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215386 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415387
15388 HttpRequestInfo request2;
15389 request2.method = "POST";
15390 request2.url = GURL("http://www.foo.com/");
15391 request2.upload_data_stream = &upload_data_stream;
15392 request2.load_flags = 0;
15393
danakj1fd259a02016-04-16 03:17:0915394 std::unique_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4115395 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415396 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
15397 EXPECT_EQ(ERR_IO_PENDING, rv);
15398
15399 rv = callback.WaitForResult();
15400 EXPECT_EQ(OK, rv);
15401
15402 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:5215403 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415404
wezca1070932016-05-26 20:30:5215405 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415406 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15407
15408 std::string response_data2;
15409 rv = ReadTransaction(trans2.get(), &response_data2);
15410 EXPECT_EQ(OK, rv);
15411 EXPECT_EQ("second response", response_data2);
15412}
15413
15414TEST_P(HttpNetworkTransactionTest,
15415 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915416 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215417 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915418 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215419 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415420
15421 HttpRequestInfo request;
15422 request.method = "POST";
15423 request.url = GURL("http://www.foo.com/");
15424 request.upload_data_stream = &upload_data_stream;
15425 request.load_flags = 0;
15426
danakj1fd259a02016-04-16 03:17:0915427 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15428 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115429 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415430 // Send headers successfully, but get an error while sending the body.
15431 MockWrite data_writes[] = {
15432 MockWrite("POST / HTTP/1.1\r\n"
15433 "Host: www.foo.com\r\n"
15434 "Connection: keep-alive\r\n"
15435 "Content-Length: 3\r\n\r\n"
15436 "fo"),
15437 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15438 };
15439
15440 MockRead data_reads[] = {
15441 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15442 MockRead("hello world"),
15443 MockRead(SYNCHRONOUS, OK),
15444 };
15445 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15446 arraysize(data_writes));
15447 session_deps_.socket_factory->AddSocketDataProvider(&data);
15448
15449 TestCompletionCallback callback;
15450
15451 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15452 EXPECT_EQ(ERR_IO_PENDING, rv);
15453
15454 rv = callback.WaitForResult();
15455 EXPECT_EQ(OK, rv);
15456
15457 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215458 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415459
wezca1070932016-05-26 20:30:5215460 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415461 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15462
15463 std::string response_data;
15464 rv = ReadTransaction(trans.get(), &response_data);
15465 EXPECT_EQ(OK, rv);
15466 EXPECT_EQ("hello world", response_data);
15467}
15468
15469// This tests the more common case than the previous test, where headers and
15470// body are not merged into a single request.
15471TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715472 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415473
15474 HttpRequestInfo request;
15475 request.method = "POST";
15476 request.url = GURL("http://www.foo.com/");
15477 request.upload_data_stream = &upload_data_stream;
15478 request.load_flags = 0;
15479
danakj1fd259a02016-04-16 03:17:0915480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15481 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115482 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415483 // Send headers successfully, but get an error while sending the body.
15484 MockWrite data_writes[] = {
15485 MockWrite("POST / HTTP/1.1\r\n"
15486 "Host: www.foo.com\r\n"
15487 "Connection: keep-alive\r\n"
15488 "Transfer-Encoding: chunked\r\n\r\n"),
15489 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15490 };
15491
15492 MockRead data_reads[] = {
15493 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15494 MockRead("hello world"),
15495 MockRead(SYNCHRONOUS, OK),
15496 };
15497 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15498 arraysize(data_writes));
15499 session_deps_.socket_factory->AddSocketDataProvider(&data);
15500
15501 TestCompletionCallback callback;
15502
15503 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15504 EXPECT_EQ(ERR_IO_PENDING, rv);
15505 // Make sure the headers are sent before adding a chunk. This ensures that
15506 // they can't be merged with the body in a single send. Not currently
15507 // necessary since a chunked body is never merged with headers, but this makes
15508 // the test more future proof.
15509 base::RunLoop().RunUntilIdle();
15510
mmenkecbc2b712014-10-09 20:29:0715511 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415512
15513 rv = callback.WaitForResult();
15514 EXPECT_EQ(OK, rv);
15515
15516 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215517 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415518
wezca1070932016-05-26 20:30:5215519 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415520 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15521
15522 std::string response_data;
15523 rv = ReadTransaction(trans.get(), &response_data);
15524 EXPECT_EQ(OK, rv);
15525 EXPECT_EQ("hello world", response_data);
15526}
15527
15528TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915529 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215530 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915531 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215532 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415533
15534 HttpRequestInfo request;
15535 request.method = "POST";
15536 request.url = GURL("http://www.foo.com/");
15537 request.upload_data_stream = &upload_data_stream;
15538 request.load_flags = 0;
15539
danakj1fd259a02016-04-16 03:17:0915540 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15541 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115542 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415543
15544 MockWrite data_writes[] = {
15545 MockWrite("POST / HTTP/1.1\r\n"
15546 "Host: www.foo.com\r\n"
15547 "Connection: keep-alive\r\n"
15548 "Content-Length: 3\r\n\r\n"),
15549 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15550 };
15551
15552 MockRead data_reads[] = {
15553 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15554 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15555 MockRead("hello world"),
15556 MockRead(SYNCHRONOUS, OK),
15557 };
15558 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15559 arraysize(data_writes));
15560 session_deps_.socket_factory->AddSocketDataProvider(&data);
15561
15562 TestCompletionCallback callback;
15563
15564 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15565 EXPECT_EQ(ERR_IO_PENDING, rv);
15566
15567 rv = callback.WaitForResult();
15568 EXPECT_EQ(OK, rv);
15569
15570 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215571 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415572
wezca1070932016-05-26 20:30:5215573 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415574 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15575
15576 std::string response_data;
15577 rv = ReadTransaction(trans.get(), &response_data);
15578 EXPECT_EQ(OK, rv);
15579 EXPECT_EQ("hello world", response_data);
15580}
15581
15582TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915583 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215584 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915585 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215586 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415587
15588 HttpRequestInfo request;
15589 request.method = "POST";
15590 request.url = GURL("http://www.foo.com/");
15591 request.upload_data_stream = &upload_data_stream;
15592 request.load_flags = 0;
15593
danakj1fd259a02016-04-16 03:17:0915594 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15595 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115596 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415597 // Send headers successfully, but get an error while sending the body.
15598 MockWrite data_writes[] = {
15599 MockWrite("POST / HTTP/1.1\r\n"
15600 "Host: www.foo.com\r\n"
15601 "Connection: keep-alive\r\n"
15602 "Content-Length: 3\r\n\r\n"),
15603 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15604 };
15605
15606 MockRead data_reads[] = {
15607 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15608 MockRead("hello world"),
15609 MockRead(SYNCHRONOUS, OK),
15610 };
15611 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15612 arraysize(data_writes));
15613 session_deps_.socket_factory->AddSocketDataProvider(&data);
15614
15615 TestCompletionCallback callback;
15616
15617 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15618 EXPECT_EQ(ERR_IO_PENDING, rv);
15619
15620 rv = callback.WaitForResult();
15621 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415622}
15623
15624TEST_P(HttpNetworkTransactionTest,
15625 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915626 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215627 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915628 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215629 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415630
15631 HttpRequestInfo request;
15632 request.method = "POST";
15633 request.url = GURL("http://www.foo.com/");
15634 request.upload_data_stream = &upload_data_stream;
15635 request.load_flags = 0;
15636
danakj1fd259a02016-04-16 03:17:0915637 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15638 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115639 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415640 // Send headers successfully, but get an error while sending the body.
15641 MockWrite data_writes[] = {
15642 MockWrite("POST / HTTP/1.1\r\n"
15643 "Host: www.foo.com\r\n"
15644 "Connection: keep-alive\r\n"
15645 "Content-Length: 3\r\n\r\n"),
15646 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15647 };
15648
15649 MockRead data_reads[] = {
15650 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15651 MockRead("HTTP/1.0 302 Redirect\r\n"),
15652 MockRead("Location: http://somewhere-else.com/\r\n"),
15653 MockRead("Content-Length: 0\r\n\r\n"),
15654 MockRead(SYNCHRONOUS, OK),
15655 };
15656 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15657 arraysize(data_writes));
15658 session_deps_.socket_factory->AddSocketDataProvider(&data);
15659
15660 TestCompletionCallback callback;
15661
15662 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15663 EXPECT_EQ(ERR_IO_PENDING, rv);
15664
15665 rv = callback.WaitForResult();
15666 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415667}
15668
15669TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915670 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215671 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915672 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215673 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415674
15675 HttpRequestInfo request;
15676 request.method = "POST";
15677 request.url = GURL("http://www.foo.com/");
15678 request.upload_data_stream = &upload_data_stream;
15679 request.load_flags = 0;
15680
danakj1fd259a02016-04-16 03:17:0915681 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15682 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115683 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415684 // Send headers successfully, but get an error while sending the body.
15685 MockWrite data_writes[] = {
15686 MockWrite("POST / HTTP/1.1\r\n"
15687 "Host: www.foo.com\r\n"
15688 "Connection: keep-alive\r\n"
15689 "Content-Length: 3\r\n\r\n"),
15690 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15691 };
15692
15693 MockRead data_reads[] = {
15694 MockRead("HTTP 0.9 rocks!"),
15695 MockRead(SYNCHRONOUS, OK),
15696 };
15697 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15698 arraysize(data_writes));
15699 session_deps_.socket_factory->AddSocketDataProvider(&data);
15700
15701 TestCompletionCallback callback;
15702
15703 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15704 EXPECT_EQ(ERR_IO_PENDING, rv);
15705
15706 rv = callback.WaitForResult();
15707 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415708}
15709
15710TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0915711 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215712 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915713 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215714 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415715
15716 HttpRequestInfo request;
15717 request.method = "POST";
15718 request.url = GURL("http://www.foo.com/");
15719 request.upload_data_stream = &upload_data_stream;
15720 request.load_flags = 0;
15721
danakj1fd259a02016-04-16 03:17:0915722 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15723 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115724 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415725 // Send headers successfully, but get an error while sending the body.
15726 MockWrite data_writes[] = {
15727 MockWrite("POST / HTTP/1.1\r\n"
15728 "Host: www.foo.com\r\n"
15729 "Connection: keep-alive\r\n"
15730 "Content-Length: 3\r\n\r\n"),
15731 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15732 };
15733
15734 MockRead data_reads[] = {
15735 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15736 MockRead(SYNCHRONOUS, OK),
15737 };
15738 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15739 arraysize(data_writes));
15740 session_deps_.socket_factory->AddSocketDataProvider(&data);
15741
15742 TestCompletionCallback callback;
15743
15744 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15745 EXPECT_EQ(ERR_IO_PENDING, rv);
15746
15747 rv = callback.WaitForResult();
15748 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415749}
15750
Adam Rice425cf122015-01-19 06:18:2415751// Verify that proxy headers are not sent to the destination server when
15752// establishing a tunnel for a secure WebSocket connection.
15753TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
15754 HttpRequestInfo request;
15755 request.method = "GET";
bncce36dca22015-04-21 22:11:2315756 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415757 AddWebSocketHeaders(&request.extra_headers);
15758
15759 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315760 session_deps_.proxy_service =
15761 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415762
danakj1fd259a02016-04-16 03:17:0915763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415764
15765 // Since a proxy is configured, try to establish a tunnel.
15766 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715767 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15768 "Host: www.example.org:443\r\n"
15769 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415770
15771 // After calling trans->RestartWithAuth(), this is the request we should
15772 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1715773 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15774 "Host: www.example.org:443\r\n"
15775 "Proxy-Connection: keep-alive\r\n"
15776 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415777
rsleevidb16bb02015-11-12 23:47:1715778 MockWrite("GET / HTTP/1.1\r\n"
15779 "Host: www.example.org\r\n"
15780 "Connection: Upgrade\r\n"
15781 "Upgrade: websocket\r\n"
15782 "Origin: http://www.example.org\r\n"
15783 "Sec-WebSocket-Version: 13\r\n"
15784 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415785 };
15786
15787 // The proxy responds to the connect with a 407, using a persistent
15788 // connection.
15789 MockRead data_reads[] = {
15790 // No credentials.
15791 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15792 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415793 MockRead("Content-Length: 0\r\n"),
15794 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415795
15796 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15797
15798 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15799 MockRead("Upgrade: websocket\r\n"),
15800 MockRead("Connection: Upgrade\r\n"),
15801 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15802 };
15803
15804 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15805 arraysize(data_writes));
15806 session_deps_.socket_factory->AddSocketDataProvider(&data);
15807 SSLSocketDataProvider ssl(ASYNC, OK);
15808 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15809
danakj1fd259a02016-04-16 03:17:0915810 std::unique_ptr<HttpTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415811 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15812 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15813 trans->SetWebSocketHandshakeStreamCreateHelper(
15814 &websocket_stream_create_helper);
15815
15816 {
15817 TestCompletionCallback callback;
15818
15819 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15820 EXPECT_EQ(ERR_IO_PENDING, rv);
15821
15822 rv = callback.WaitForResult();
15823 EXPECT_EQ(OK, rv);
15824 }
15825
15826 const HttpResponseInfo* response = trans->GetResponseInfo();
15827 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215828 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415829 EXPECT_EQ(407, response->headers->response_code());
15830
15831 {
15832 TestCompletionCallback callback;
15833
15834 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15835 callback.callback());
15836 EXPECT_EQ(ERR_IO_PENDING, rv);
15837
15838 rv = callback.WaitForResult();
15839 EXPECT_EQ(OK, rv);
15840 }
15841
15842 response = trans->GetResponseInfo();
15843 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215844 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415845
15846 EXPECT_EQ(101, response->headers->response_code());
15847
15848 trans.reset();
15849 session->CloseAllConnections();
15850}
15851
15852// Verify that proxy headers are not sent to the destination server when
15853// establishing a tunnel for an insecure WebSocket connection.
15854// This requires the authentication info to be injected into the auth cache
15855// due to crbug.com/395064
15856// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
15857TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
15858 HttpRequestInfo request;
15859 request.method = "GET";
bncce36dca22015-04-21 22:11:2315860 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415861 AddWebSocketHeaders(&request.extra_headers);
15862
15863 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315864 session_deps_.proxy_service =
15865 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415866
danakj1fd259a02016-04-16 03:17:0915867 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415868
15869 MockWrite data_writes[] = {
15870 // Try to establish a tunnel for the WebSocket connection, with
15871 // credentials. Because WebSockets have a separate set of socket pools,
15872 // they cannot and will not use the same TCP/IP connection as the
15873 // preflight HTTP request.
15874 MockWrite(
bncce36dca22015-04-21 22:11:2315875 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15876 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415877 "Proxy-Connection: keep-alive\r\n"
15878 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15879
15880 MockWrite(
15881 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315882 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415883 "Connection: Upgrade\r\n"
15884 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315885 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415886 "Sec-WebSocket-Version: 13\r\n"
15887 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15888 };
15889
15890 MockRead data_reads[] = {
15891 // HTTP CONNECT with credentials.
15892 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15893
15894 // WebSocket connection established inside tunnel.
15895 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15896 MockRead("Upgrade: websocket\r\n"),
15897 MockRead("Connection: Upgrade\r\n"),
15898 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15899 };
15900
15901 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15902 arraysize(data_writes));
15903 session_deps_.socket_factory->AddSocketDataProvider(&data);
15904
15905 session->http_auth_cache()->Add(
15906 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
15907 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
15908
danakj1fd259a02016-04-16 03:17:0915909 std::unique_ptr<HttpTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415910 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15911 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15912 trans->SetWebSocketHandshakeStreamCreateHelper(
15913 &websocket_stream_create_helper);
15914
15915 TestCompletionCallback callback;
15916
15917 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15918 EXPECT_EQ(ERR_IO_PENDING, rv);
15919
15920 rv = callback.WaitForResult();
15921 EXPECT_EQ(OK, rv);
15922
15923 const HttpResponseInfo* response = trans->GetResponseInfo();
15924 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215925 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415926
15927 EXPECT_EQ(101, response->headers->response_code());
15928
15929 trans.reset();
15930 session->CloseAllConnections();
15931}
15932
sclittlefb249892015-09-10 21:33:2215933TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0915934 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215935 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915936 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215937 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215938
15939 HttpRequestInfo request;
15940 request.method = "POST";
15941 request.url = GURL("http://www.foo.com/");
15942 request.upload_data_stream = &upload_data_stream;
15943
danakj1fd259a02016-04-16 03:17:0915944 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15945 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2215946 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15947 MockWrite data_writes[] = {
15948 MockWrite("POST / HTTP/1.1\r\n"
15949 "Host: www.foo.com\r\n"
15950 "Connection: keep-alive\r\n"
15951 "Content-Length: 3\r\n\r\n"),
15952 MockWrite("foo"),
15953 };
15954
15955 MockRead data_reads[] = {
15956 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15957 MockRead(SYNCHRONOUS, OK),
15958 };
15959 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15960 arraysize(data_writes));
15961 session_deps_.socket_factory->AddSocketDataProvider(&data);
15962
15963 TestCompletionCallback callback;
15964
15965 EXPECT_EQ(ERR_IO_PENDING,
15966 trans->Start(&request, callback.callback(), BoundNetLog()));
15967 EXPECT_EQ(OK, callback.WaitForResult());
15968
15969 std::string response_data;
15970 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15971
15972 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15973 trans->GetTotalSentBytes());
15974 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15975 trans->GetTotalReceivedBytes());
15976}
15977
15978TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0915979 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215980 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915981 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215982 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215983
15984 HttpRequestInfo request;
15985 request.method = "POST";
15986 request.url = GURL("http://www.foo.com/");
15987 request.upload_data_stream = &upload_data_stream;
15988
danakj1fd259a02016-04-16 03:17:0915989 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15990 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2215991 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15992 MockWrite data_writes[] = {
15993 MockWrite("POST / HTTP/1.1\r\n"
15994 "Host: www.foo.com\r\n"
15995 "Connection: keep-alive\r\n"
15996 "Content-Length: 3\r\n\r\n"),
15997 MockWrite("foo"),
15998 };
15999
16000 MockRead data_reads[] = {
16001 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16002 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16003 MockRead(SYNCHRONOUS, OK),
16004 };
16005 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16006 arraysize(data_writes));
16007 session_deps_.socket_factory->AddSocketDataProvider(&data);
16008
16009 TestCompletionCallback callback;
16010
16011 EXPECT_EQ(ERR_IO_PENDING,
16012 trans->Start(&request, callback.callback(), BoundNetLog()));
16013 EXPECT_EQ(OK, callback.WaitForResult());
16014
16015 std::string response_data;
16016 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
16017
16018 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
16019 trans->GetTotalSentBytes());
16020 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
16021 trans->GetTotalReceivedBytes());
16022}
16023
16024TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216025 ChunkedUploadDataStream upload_data_stream(0);
16026
16027 HttpRequestInfo request;
16028 request.method = "POST";
16029 request.url = GURL("http://www.foo.com/");
16030 request.upload_data_stream = &upload_data_stream;
16031
danakj1fd259a02016-04-16 03:17:0916032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16033 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2216034 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16035 // Send headers successfully, but get an error while sending the body.
16036 MockWrite data_writes[] = {
16037 MockWrite("POST / HTTP/1.1\r\n"
16038 "Host: www.foo.com\r\n"
16039 "Connection: keep-alive\r\n"
16040 "Transfer-Encoding: chunked\r\n\r\n"),
16041 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16042 };
16043
16044 MockRead data_reads[] = {
16045 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16046 MockRead(SYNCHRONOUS, OK),
16047 };
16048 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16049 arraysize(data_writes));
16050 session_deps_.socket_factory->AddSocketDataProvider(&data);
16051
16052 TestCompletionCallback callback;
16053
16054 EXPECT_EQ(ERR_IO_PENDING,
16055 trans->Start(&request, callback.callback(), BoundNetLog()));
16056
16057 base::RunLoop().RunUntilIdle();
16058 upload_data_stream.AppendData("f", 1, false);
16059
16060 base::RunLoop().RunUntilIdle();
16061 upload_data_stream.AppendData("oo", 2, true);
16062
16063 EXPECT_EQ(OK, callback.WaitForResult());
16064
16065 std::string response_data;
16066 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
16067
16068 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
16069 trans->GetTotalSentBytes());
16070 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
16071 trans->GetTotalReceivedBytes());
16072}
16073
bncf4588402015-11-24 13:33:1816074TEST_P(HttpNetworkTransactionTest, EnableNPN) {
bncf4588402015-11-24 13:33:1816075 session_deps_.enable_npn = true;
16076
danakj1fd259a02016-04-16 03:17:0916077 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncf4588402015-11-24 13:33:1816078 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
nharper8cdb0fb2016-04-22 21:34:5916079 HttpRequestInfo request;
16080 TestCompletionCallback callback;
16081 EXPECT_EQ(ERR_IO_PENDING,
16082 trans.Start(&request, callback.callback(), BoundNetLog()));
bncf4588402015-11-24 13:33:1816083
16084 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
16085 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
16086 EXPECT_THAT(trans.server_ssl_config_.npn_protos,
16087 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
16088}
16089
16090TEST_P(HttpNetworkTransactionTest, DisableNPN) {
bncf4588402015-11-24 13:33:1816091 session_deps_.enable_npn = false;
16092
danakj1fd259a02016-04-16 03:17:0916093 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncf4588402015-11-24 13:33:1816094 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
nharper8cdb0fb2016-04-22 21:34:5916095 HttpRequestInfo request;
16096 TestCompletionCallback callback;
16097 EXPECT_EQ(ERR_IO_PENDING,
16098 trans.Start(&request, callback.callback(), BoundNetLog()));
bncf4588402015-11-24 13:33:1816099
16100 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
16101 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
16102 EXPECT_TRUE(trans.server_ssl_config_.npn_protos.empty());
16103}
16104
nharperb7441ef2016-01-25 23:54:1416105#if !defined(OS_IOS)
16106TEST_P(HttpNetworkTransactionTest, TokenBindingSpdy) {
16107 const std::string https_url = "https://www.example.com";
16108 HttpRequestInfo request;
16109 request.url = GURL(https_url);
16110 request.method = "GET";
16111
16112 SSLSocketDataProvider ssl(ASYNC, OK);
16113 ssl.token_binding_negotiated = true;
16114 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
16115 ssl.SetNextProto(GetProtocol());
16116 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16117
danakj1fd259a02016-04-16 03:17:0916118 std::unique_ptr<SpdySerializedFrame> resp(
nharperb7441ef2016-01-25 23:54:1416119 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0916120 std::unique_ptr<SpdySerializedFrame> body(
bncb03b1092016-04-06 11:19:5516121 spdy_util_.ConstructSpdyBodyFrame(1, true));
nharperb7441ef2016-01-25 23:54:1416122 MockRead reads[] = {CreateMockRead(*resp), CreateMockRead(*body),
16123 MockRead(ASYNC, ERR_IO_PENDING)};
16124 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16125 session_deps_.socket_factory->AddSocketDataProvider(&data);
16126 session_deps_.channel_id_service.reset(new ChannelIDService(
16127 new DefaultChannelIDStore(nullptr), base::ThreadTaskRunnerHandle::Get()));
danakj1fd259a02016-04-16 03:17:0916128 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416129
16130 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16131 TestCompletionCallback callback;
16132 EXPECT_EQ(ERR_IO_PENDING,
16133 trans.Start(&request, callback.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5516134 base::RunLoop().RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416135
16136 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16137 HttpRequestHeaders headers;
16138 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16139 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16140}
16141#endif // !defined(OS_IOS)
16142
[email protected]89ceba9a2009-03-21 03:46:0616143} // namespace net