blob: 6be19d7e4081579c862a5fc9fd6198bc2033ac46 [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>
avibf0746c2015-12-09 19:53:1410#include <limits>
[email protected]5285d972011-10-18 18:56:3411#include <string>
dchengc7eeda422015-12-26 03:56:4812#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3313#include <vector>
[email protected]77848d12008-11-14 00:00:2214
[email protected]68bf9152008-09-25 19:47:3015#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5216#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2917#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5718#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2419#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4620#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:1521#include "base/memory/scoped_ptr.h"
[email protected]bf828982013-08-14 18:01:4722#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4923#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4724#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0525#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3326#include "base/test/test_file_util.h"
skyostil4891b25b2015-06-11 11:43:4527#include "base/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3528#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0729#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3330#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0731#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2532#include "net/base/load_timing_info.h"
33#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2434#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1535#include "net/base/proxy_delegate.h"
[email protected]ac790b42009-12-02 04:31:3136#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5237#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4038#include "net/base/test_data_directory.h"
tbansal28e68f82016-02-04 02:56:1539#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0640#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2141#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1142#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1643#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5344#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2445#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1246#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0047#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2948#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1949#include "net/http/http_auth_scheme.h"
Adam Rice425cf122015-01-19 06:18:2450#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5751#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5252#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5653#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2454#include "net/http/http_request_headers.h"
[email protected]17291a022011-10-10 07:32:5355#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5756#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3857#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2458#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1959#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0760#include "net/log/net_log.h"
vishal.b62985ca92015-04-17 08:45:5161#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4662#include "net/log/test_net_log_entry.h"
63#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1364#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5365#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0366#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1167#include "net/proxy/proxy_resolver.h"
tbansal28e68f82016-02-04 02:56:1568#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1169#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4470#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1571#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0372#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4773#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0274#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0775#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4476#include "net/socket/socket_test_util.h"
77#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5478#include "net/spdy/spdy_framer.h"
79#include "net/spdy/spdy_session.h"
80#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0281#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1482#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5783#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0384#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5785#include "net/ssl/ssl_config_service_defaults.h"
86#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5487#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1188#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4489#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:1890#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:5291#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1592#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2793#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5294
[email protected]ad65a3e2013-12-25 18:18:0195using base::ASCIIToUTF16;
96
initial.commit586acc5fe2008-07-26 22:42:5297//-----------------------------------------------------------------------------
98
ttuttle859dc7a2015-04-23 19:42:2999namespace net {
100
[email protected]13c8a092010-07-29 06:15:44101namespace {
102
rdsmithebb50aa2015-11-12 03:44:38103enum TestCase {
104 // Test using the SPDY/3.1 protocol.
105 kTestCaseSPDY31,
106
107 // Test using the HTTP/2 protocol, without specifying a stream
108 // dependency based on the RequestPriority.
109 kTestCaseHTTP2NoPriorityDependencies,
110
111 // Test using the HTTP/2 protocol, specifying a stream
112 // dependency based on the RequestPriority.
113 kTestCaseHTTP2PriorityDependencies
114};
115
[email protected]42cba2fb2013-03-29 19:58:57116const base::string16 kBar(ASCIIToUTF16("bar"));
117const base::string16 kBar2(ASCIIToUTF16("bar2"));
118const base::string16 kBar3(ASCIIToUTF16("bar3"));
119const base::string16 kBaz(ASCIIToUTF16("baz"));
120const base::string16 kFirst(ASCIIToUTF16("first"));
121const base::string16 kFoo(ASCIIToUTF16("foo"));
122const base::string16 kFoo2(ASCIIToUTF16("foo2"));
123const base::string16 kFoo3(ASCIIToUTF16("foo3"));
124const base::string16 kFou(ASCIIToUTF16("fou"));
125const base::string16 kSecond(ASCIIToUTF16("second"));
126const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
127const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44128
ttuttle859dc7a2015-04-23 19:42:29129int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
130 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
131 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02132}
133
ttuttle859dc7a2015-04-23 19:42:29134int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
135 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
136 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02137}
138
ttuttle859dc7a2015-04-23 19:42:29139bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
140 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
141 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52142}
143
[email protected]f3da152d2012-06-02 01:00:57144// Takes in a Value created from a NetLogHttpResponseParameter, and returns
145// a JSONified list of headers as a single string. Uses single quotes instead
146// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27147bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57148 if (!params)
149 return false;
[email protected]ea5ef4c2013-06-13 22:50:27150 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57151 if (!params->GetList("headers", &header_list))
152 return false;
153 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34154 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28155 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57156 return true;
157}
158
[email protected]029c83b62013-01-24 05:28:20159// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
160// used.
ttuttle859dc7a2015-04-23 19:42:29161void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20162 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29163 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25164
[email protected]029c83b62013-01-24 05:28:20165 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
166 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
167
ttuttle859dc7a2015-04-23 19:42:29168 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20169 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25170
171 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25172
[email protected]3b23a222013-05-15 21:33:25173 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25174 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
175 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25176 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25177}
178
[email protected]029c83b62013-01-24 05:28:20179// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
180// used.
ttuttle859dc7a2015-04-23 19:42:29181void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25182 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20183 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29184 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20185
186 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
187 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
188
ttuttle859dc7a2015-04-23 19:42:29189 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
190 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20191 EXPECT_LE(load_timing_info.connect_timing.connect_end,
192 load_timing_info.send_start);
193
194 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20195
[email protected]3b23a222013-05-15 21:33:25196 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20197 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
198 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25199 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20200}
201
202// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
203// used.
ttuttle859dc7a2015-04-23 19:42:29204void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20205 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29206 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20207
ttuttle859dc7a2015-04-23 19:42:29208 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20209
210 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
211 EXPECT_LE(load_timing_info.proxy_resolve_start,
212 load_timing_info.proxy_resolve_end);
213 EXPECT_LE(load_timing_info.proxy_resolve_end,
214 load_timing_info.send_start);
215 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20216
[email protected]3b23a222013-05-15 21:33:25217 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20218 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
219 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25220 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20221}
222
223// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
224// used.
ttuttle859dc7a2015-04-23 19:42:29225void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20226 int connect_timing_flags) {
227 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29228 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20229
230 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
231 EXPECT_LE(load_timing_info.proxy_resolve_start,
232 load_timing_info.proxy_resolve_end);
233 EXPECT_LE(load_timing_info.proxy_resolve_end,
234 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29235 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
236 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20237 EXPECT_LE(load_timing_info.connect_timing.connect_end,
238 load_timing_info.send_start);
239
240 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20241
[email protected]3b23a222013-05-15 21:33:25242 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20243 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
244 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25245 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25246}
247
ttuttle859dc7a2015-04-23 19:42:29248void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24249 headers->SetHeader("Connection", "Upgrade");
250 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23251 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24252 headers->SetHeader("Sec-WebSocket-Version", "13");
253 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
254}
255
mmenkee65e7af2015-10-13 17:16:42256scoped_ptr<HttpNetworkSession> CreateSession(
257 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34258 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14259}
260
[email protected]448d4ca52012-03-04 04:12:23261} // namespace
262
[email protected]23e482282013-06-14 16:08:02263class HttpNetworkTransactionTest
264 : public PlatformTest,
rdsmithebb50aa2015-11-12 03:44:38265 public ::testing::WithParamInterface<TestCase> {
[email protected]483fa202013-05-14 01:07:03266 public:
[email protected]23e482282013-06-14 16:08:02267 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03268 // Important to restore the per-pool limit first, since the pool limit must
269 // always be greater than group limit, and the tests reduce both limits.
270 ClientSocketPoolManager::set_max_sockets_per_pool(
271 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
272 ClientSocketPoolManager::set_max_sockets_per_group(
273 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
[email protected]483fa202013-05-14 01:07:03274 }
275
[email protected]e3ceb682011-06-28 23:55:46276 protected:
[email protected]23e482282013-06-14 16:08:02277 HttpNetworkTransactionTest()
rdsmithebb50aa2015-11-12 03:44:38278 : spdy_util_(GetProtocol(), GetDependenciesFromPriority()),
279 session_deps_(GetProtocol()),
[email protected]483fa202013-05-14 01:07:03280 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
281 HttpNetworkSession::NORMAL_SOCKET_POOL)),
282 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
283 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
rdsmith2e54d1f2016-03-21 19:48:17284 session_deps_.enable_priority_dependencies = GetDependenciesFromPriority();
[email protected]483fa202013-05-14 01:07:03285 }
[email protected]bb88e1d32013-05-03 23:11:07286
[email protected]e3ceb682011-06-28 23:55:46287 struct SimpleGetHelperResult {
288 int rv;
289 std::string status_line;
290 std::string response_data;
sclittlefb249892015-09-10 21:33:22291 int64_t total_received_bytes;
292 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25293 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47294 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59295 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46296 };
297
dcheng67be2b1f2014-10-27 21:47:29298 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50299 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34300 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54301 }
302
dcheng67be2b1f2014-10-27 21:47:29303 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50304 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34305 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09306 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34307 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09308 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50309 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34310 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09311 }
312
rdsmithebb50aa2015-11-12 03:44:38313 NextProto GetProtocol() const {
314 return GetParam() == kTestCaseSPDY31 ? kProtoSPDY31 : kProtoHTTP2;
315 }
316
317 bool GetDependenciesFromPriority() const {
318 return GetParam() == kTestCaseHTTP2PriorityDependencies;
319 }
320
bnc33b8cef42014-11-19 17:30:38321 const char* GetAlternateProtocolFromParam() {
rdsmithebb50aa2015-11-12 03:44:38322 return AlternateProtocolToString(
323 AlternateProtocolFromNextProto(GetProtocol()));
bnc33b8cef42014-11-19 17:30:38324 }
325
bncc958faa2015-07-31 18:14:52326 std::string GetAlternativeServiceHttpHeader() {
327 return std::string("Alt-Svc: ") + GetAlternateProtocolFromParam() +
328 "=\"www.example.com:443\"\r\n";
329 }
330
[email protected]8a0fc822013-06-27 20:52:43331 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38332 return std::string("Alternate-Protocol: 443:") +
bncc958faa2015-07-31 18:14:52333 GetAlternateProtocolFromParam() + "\r\n";
[email protected]8a0fc822013-06-27 20:52:43334 }
335
[email protected]202965992011-12-07 23:04:51336 // Either |write_failure| specifies a write failure or |read_failure|
337 // specifies a read failure when using a reused socket. In either case, the
338 // failure should cause the network transaction to resend the request, and the
339 // other argument should be NULL.
340 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
341 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52342
[email protected]a34f61ee2014-03-18 20:59:49343 // Either |write_failure| specifies a write failure or |read_failure|
344 // specifies a read failure when using a reused socket. In either case, the
345 // failure should cause the network transaction to resend the request, and the
346 // other argument should be NULL.
347 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10348 const MockRead* read_failure,
349 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49350
[email protected]5a60c8b2011-10-19 20:14:29351 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
352 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15353 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52354
[email protected]ff007e162009-05-23 09:13:15355 HttpRequestInfo request;
356 request.method = "GET";
bncce36dca22015-04-21 22:11:23357 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15358 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52359
vishal.b62985ca92015-04-17 08:45:51360 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07361 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:42362 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27363 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27365
[email protected]5a60c8b2011-10-19 20:14:29366 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07367 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29368 }
initial.commit586acc5fe2008-07-26 22:42:52369
[email protected]49639fa2011-12-20 23:22:41370 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52371
eroman24bc6a12015-05-06 19:55:48372 EXPECT_TRUE(log.bound().IsCapturing());
[email protected]49639fa2011-12-20 23:22:41373 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15374 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52375
[email protected]ff007e162009-05-23 09:13:15376 out.rv = callback.WaitForResult();
sclittlefb249892015-09-10 21:33:22377 out.total_received_bytes = trans->GetTotalReceivedBytes();
378 out.total_sent_bytes = trans->GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25379
380 // Even in the failure cases that use this function, connections are always
381 // successfully established before the error.
382 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
383 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
384
[email protected]ff007e162009-05-23 09:13:15385 if (out.rv != OK)
386 return out;
387
388 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50389 // Can't use ASSERT_* inside helper functions like this, so
390 // return an error.
[email protected]90499482013-06-01 00:39:50391 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50392 out.rv = ERR_UNEXPECTED;
393 return out;
394 }
[email protected]ff007e162009-05-23 09:13:15395 out.status_line = response->headers->GetStatusLine();
396
[email protected]80a09a82012-11-16 17:40:06397 EXPECT_EQ("127.0.0.1", response->socket_address.host());
398 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19399
ttuttled9dbc652015-09-29 20:00:59400 bool got_endpoint =
401 trans->GetRemoteEndpoint(&out.remote_endpoint_after_start);
402 EXPECT_EQ(got_endpoint,
403 out.remote_endpoint_after_start.address().size() > 0);
404
[email protected]ff007e162009-05-23 09:13:15405 rv = ReadTransaction(trans.get(), &out.response_data);
406 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40407
mmenke43758e62015-05-04 21:09:46408 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40409 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39410 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40411 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12412 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39413 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40414 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39415 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
416 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15417
[email protected]f3da152d2012-06-02 01:00:57418 std::string line;
419 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
420 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
421
[email protected]79e1fd62013-06-20 06:50:04422 HttpRequestHeaders request_headers;
423 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
424 std::string value;
425 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23426 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04427 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
428 EXPECT_EQ("keep-alive", value);
429
430 std::string response_headers;
431 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23432 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04433 response_headers);
[email protected]3deb9a52010-11-11 00:24:40434
sclittlefb249892015-09-10 21:33:22435 out.total_received_bytes = trans->GetTotalReceivedBytes();
436 // The total number of sent bytes should not have changed.
437 EXPECT_EQ(out.total_sent_bytes, trans->GetTotalSentBytes());
438
ttuttle1f2d7e92015-04-28 16:17:47439 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47440 return out;
[email protected]ff007e162009-05-23 09:13:15441 }
initial.commit586acc5fe2008-07-26 22:42:52442
[email protected]5a60c8b2011-10-19 20:14:29443 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
444 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22445 MockWrite data_writes[] = {
446 MockWrite("GET / HTTP/1.1\r\n"
447 "Host: www.example.org\r\n"
448 "Connection: keep-alive\r\n\r\n"),
449 };
[email protected]5a60c8b2011-10-19 20:14:29450
sclittlefb249892015-09-10 21:33:22451 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
452 arraysize(data_writes));
453 StaticSocketDataProvider* data[] = {&reads};
454 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
455
456 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
457 out.total_sent_bytes);
458 return out;
[email protected]b8015c42013-12-24 15:18:19459 }
460
[email protected]ff007e162009-05-23 09:13:15461 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
462 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52463
[email protected]ff007e162009-05-23 09:13:15464 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07465
466 void BypassHostCacheOnRefreshHelper(int load_flags);
467
468 void CheckErrorIsPassedBack(int error, IoMode mode);
469
[email protected]4bd46222013-05-14 19:32:23470 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07471 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03472
473 // Original socket limits. Some tests set these. Safest to always restore
474 // them once each test has been run.
475 int old_max_group_sockets_;
476 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15477};
[email protected]231d5a32008-09-13 00:45:27478
rdsmithebb50aa2015-11-12 03:44:38479INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc57685ae62015-03-10 21:27:20480 HttpNetworkTransactionTest,
rdsmithebb50aa2015-11-12 03:44:38481 testing::Values(kTestCaseSPDY31,
482 kTestCaseHTTP2NoPriorityDependencies,
483 kTestCaseHTTP2PriorityDependencies));
[email protected]23e482282013-06-14 16:08:02484
[email protected]448d4ca52012-03-04 04:12:23485namespace {
486
[email protected]1826a402014-01-08 15:40:48487class BeforeNetworkStartHandler {
488 public:
489 explicit BeforeNetworkStartHandler(bool defer)
490 : defer_on_before_network_start_(defer),
491 observed_before_network_start_(false) {}
492
493 void OnBeforeNetworkStart(bool* defer) {
494 *defer = defer_on_before_network_start_;
495 observed_before_network_start_ = true;
496 }
497
498 bool observed_before_network_start() const {
499 return observed_before_network_start_;
500 }
501
502 private:
503 const bool defer_on_before_network_start_;
504 bool observed_before_network_start_;
505
506 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
507};
508
[email protected]597a1ab2014-06-26 08:12:27509class BeforeProxyHeadersSentHandler {
510 public:
511 BeforeProxyHeadersSentHandler()
512 : observed_before_proxy_headers_sent_(false) {}
513
[email protected]1252d42f2014-07-01 21:20:20514 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
515 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27516 observed_before_proxy_headers_sent_ = true;
517 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
518 }
519
520 bool observed_before_proxy_headers_sent() const {
521 return observed_before_proxy_headers_sent_;
522 }
523
524 std::string observed_proxy_server_uri() const {
525 return observed_proxy_server_uri_;
526 }
527
528 private:
529 bool observed_before_proxy_headers_sent_;
530 std::string observed_proxy_server_uri_;
531
532 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
533};
534
[email protected]15a5ccf82008-10-23 19:57:43535// Fill |str| with a long header list that consumes >= |size| bytes.
536void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51537 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19538 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
539 const int sizeof_row = strlen(row);
540 const int num_rows = static_cast<int>(
541 ceil(static_cast<float>(size) / sizeof_row));
542 const int sizeof_data = num_rows * sizeof_row;
543 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43544 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51545
[email protected]4ddaf2502008-10-23 18:26:19546 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43547 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19548}
549
thakis84dff942015-07-28 20:47:38550#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29551// Alternative functions that eliminate randomness and dependency on the local
552// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14553void MockGenerateRandom1(uint8_t* output, size_t n) {
554 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
555 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29556 static size_t current_byte = 0;
557 for (size_t i = 0; i < n; ++i) {
558 output[i] = bytes[current_byte++];
559 current_byte %= arraysize(bytes);
560 }
561}
562
avibf0746c2015-12-09 19:53:14563void MockGenerateRandom2(uint8_t* output, size_t n) {
564 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
565 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
566 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29567 static size_t current_byte = 0;
568 for (size_t i = 0; i < n; ++i) {
569 output[i] = bytes[current_byte++];
570 current_byte %= arraysize(bytes);
571 }
572}
573
[email protected]fe2bc6a2009-03-23 16:52:20574std::string MockGetHostName() {
575 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29576}
thakis84dff942015-07-28 20:47:38577#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29578
[email protected]e60e47a2010-07-14 03:37:18579template<typename ParentPool>
580class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31581 public:
[email protected]9e1bdd32011-02-03 21:48:34582 CaptureGroupNameSocketPool(HostResolver* host_resolver,
583 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18584
[email protected]d80a4322009-08-14 07:07:49585 const std::string last_group_name_received() const {
586 return last_group_name_;
587 }
588
dmichaeld6e570d2014-12-18 22:30:57589 int RequestSocket(const std::string& group_name,
590 const void* socket_params,
591 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15592 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57593 ClientSocketHandle* handle,
594 const CompletionCallback& callback,
595 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31596 last_group_name_ = group_name;
597 return ERR_IO_PENDING;
598 }
dmichaeld6e570d2014-12-18 22:30:57599 void CancelRequest(const std::string& group_name,
600 ClientSocketHandle* handle) override {}
601 void ReleaseSocket(const std::string& group_name,
602 scoped_ptr<StreamSocket> socket,
603 int id) override {}
604 void CloseIdleSockets() override {}
605 int IdleSocketCount() const override { return 0; }
606 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31607 return 0;
608 }
dmichaeld6e570d2014-12-18 22:30:57609 LoadState GetLoadState(const std::string& group_name,
610 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31611 return LOAD_STATE_IDLE;
612 }
dmichaeld6e570d2014-12-18 22:30:57613 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26614 return base::TimeDelta();
615 }
[email protected]d80a4322009-08-14 07:07:49616
617 private:
[email protected]04e5be32009-06-26 20:00:31618 std::string last_group_name_;
619};
620
[email protected]ab739042011-04-07 15:22:28621typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
622CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13623typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
624CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06625typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11626CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18627typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
628CaptureGroupNameSSLSocketPool;
629
rkaplowd90695c2015-03-25 22:12:41630template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18631CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34632 HostResolver* host_resolver,
633 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41634 : ParentPool(0, 0, host_resolver, NULL, NULL) {
635}
[email protected]e60e47a2010-07-14 03:37:18636
hashimoto0d3e4fb2015-01-09 05:02:50637template <>
[email protected]2df19bb2010-08-25 20:13:46638CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21639 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34640 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41641 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50642}
[email protected]2df19bb2010-08-25 20:13:46643
[email protected]007b3f82013-04-09 08:46:45644template <>
[email protected]e60e47a2010-07-14 03:37:18645CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21646 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34647 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45648 : SSLClientSocketPool(0,
649 0,
[email protected]007b3f82013-04-09 08:46:45650 cert_verifier,
651 NULL,
652 NULL,
[email protected]284303b62013-11-28 15:11:54653 NULL,
eranm6571b2b2014-12-03 15:53:23654 NULL,
[email protected]007b3f82013-04-09 08:46:45655 std::string(),
656 NULL,
657 NULL,
658 NULL,
659 NULL,
660 NULL,
[email protected]8e458552014-08-05 00:02:15661 NULL) {
662}
[email protected]2227c692010-05-04 15:36:11663
[email protected]231d5a32008-09-13 00:45:27664//-----------------------------------------------------------------------------
665
[email protected]79cb5c12011-09-12 13:12:04666// Helper functions for validating that AuthChallengeInfo's are correctly
667// configured for common cases.
668bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
669 if (!auth_challenge)
670 return false;
671 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23672 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04673 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19674 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04675 return true;
676}
677
678bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
679 if (!auth_challenge)
680 return false;
681 EXPECT_TRUE(auth_challenge->is_proxy);
682 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
683 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19684 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04685 return true;
686}
687
688bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
689 if (!auth_challenge)
690 return false;
691 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23692 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04693 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19694 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04695 return true;
696}
697
thakis84dff942015-07-28 20:47:38698#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04699bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
700 if (!auth_challenge)
701 return false;
702 EXPECT_FALSE(auth_challenge->is_proxy);
703 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
704 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19705 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04706 return true;
707}
thakis84dff942015-07-28 20:47:38708#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04709
[email protected]448d4ca52012-03-04 04:12:23710} // namespace
711
[email protected]23e482282013-06-14 16:08:02712TEST_P(HttpNetworkTransactionTest, Basic) {
mmenkee65e7af2015-10-13 17:16:42713 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40714 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41715 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27716}
717
[email protected]23e482282013-06-14 16:08:02718TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27719 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35720 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
721 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06722 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27723 };
[email protected]31a2bfe2010-02-09 08:03:39724 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
725 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42726 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27727 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
728 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22729 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
730 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47731 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59732
733 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27734}
735
736// Response with no status line.
[email protected]23e482282013-06-14 16:08:02737TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27738 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35739 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06740 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27741 };
[email protected]31a2bfe2010-02-09 08:03:39742 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
743 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42744 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27745 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
746 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22747 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
748 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27749}
750
751// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02752TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27753 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35754 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06755 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27756 };
[email protected]31a2bfe2010-02-09 08:03:39757 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
758 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42759 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27760 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
761 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22762 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
763 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27764}
765
766// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02767TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27768 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35769 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06770 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27771 };
[email protected]31a2bfe2010-02-09 08:03:39772 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
773 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42774 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27775 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
776 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22777 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
778 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27779}
780
781// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02782TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27783 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35784 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06785 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27786 };
[email protected]31a2bfe2010-02-09 08:03:39787 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
788 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42789 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25790 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
791 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
sclittlefb249892015-09-10 21:33:22792 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
793 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27794}
795
796// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02797TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27798 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35799 MockRead("\n"),
800 MockRead("\n"),
801 MockRead("Q"),
802 MockRead("J"),
803 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06804 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27805 };
[email protected]31a2bfe2010-02-09 08:03:39806 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
807 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42808 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27809 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
810 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22811 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
812 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27813}
814
815// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02816TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27817 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35818 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06819 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27820 };
[email protected]31a2bfe2010-02-09 08:03:39821 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
822 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42823 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27824 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
825 EXPECT_EQ("HTT", out.response_data);
sclittlefb249892015-09-10 21:33:22826 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
827 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52828}
829
[email protected]f9d44aa2008-09-23 23:57:17830// Simulate a 204 response, lacking a Content-Length header, sent over a
831// persistent connection. The response should still terminate since a 204
832// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02833TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19834 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17835 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35836 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19837 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06838 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17839 };
[email protected]31a2bfe2010-02-09 08:03:39840 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
841 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42842 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17843 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
844 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22845 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
846 int64_t response_size = reads_size - strlen(junk);
847 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17848}
849
[email protected]0877e3d2009-10-17 22:29:57850// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02851TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19852 std::string final_chunk = "0\r\n\r\n";
853 std::string extra_data = "HTTP/1.1 200 OK\r\n";
854 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57855 MockRead data_reads[] = {
856 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
857 MockRead("5\r\nHello\r\n"),
858 MockRead("1\r\n"),
859 MockRead(" \r\n"),
860 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19861 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06862 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57863 };
[email protected]31a2bfe2010-02-09 08:03:39864 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
865 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57866 EXPECT_EQ(OK, out.rv);
867 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
868 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22869 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
870 int64_t response_size = reads_size - extra_data.size();
871 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57872}
873
[email protected]9fe44f52010-09-23 18:36:00874// Next tests deal with http://crbug.com/56344.
875
[email protected]23e482282013-06-14 16:08:02876TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00877 MultipleContentLengthHeadersNoTransferEncoding) {
878 MockRead data_reads[] = {
879 MockRead("HTTP/1.1 200 OK\r\n"),
880 MockRead("Content-Length: 10\r\n"),
881 MockRead("Content-Length: 5\r\n\r\n"),
882 };
883 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
884 arraysize(data_reads));
885 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
886}
887
[email protected]23e482282013-06-14 16:08:02888TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04889 DuplicateContentLengthHeadersNoTransferEncoding) {
890 MockRead data_reads[] = {
891 MockRead("HTTP/1.1 200 OK\r\n"),
892 MockRead("Content-Length: 5\r\n"),
893 MockRead("Content-Length: 5\r\n\r\n"),
894 MockRead("Hello"),
895 };
896 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
897 arraysize(data_reads));
898 EXPECT_EQ(OK, out.rv);
899 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
900 EXPECT_EQ("Hello", out.response_data);
901}
902
[email protected]23e482282013-06-14 16:08:02903TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04904 ComplexContentLengthHeadersNoTransferEncoding) {
905 // More than 2 dupes.
906 {
907 MockRead data_reads[] = {
908 MockRead("HTTP/1.1 200 OK\r\n"),
909 MockRead("Content-Length: 5\r\n"),
910 MockRead("Content-Length: 5\r\n"),
911 MockRead("Content-Length: 5\r\n\r\n"),
912 MockRead("Hello"),
913 };
914 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
915 arraysize(data_reads));
916 EXPECT_EQ(OK, out.rv);
917 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
918 EXPECT_EQ("Hello", out.response_data);
919 }
920 // HTTP/1.0
921 {
922 MockRead data_reads[] = {
923 MockRead("HTTP/1.0 200 OK\r\n"),
924 MockRead("Content-Length: 5\r\n"),
925 MockRead("Content-Length: 5\r\n"),
926 MockRead("Content-Length: 5\r\n\r\n"),
927 MockRead("Hello"),
928 };
929 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
930 arraysize(data_reads));
931 EXPECT_EQ(OK, out.rv);
932 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
933 EXPECT_EQ("Hello", out.response_data);
934 }
935 // 2 dupes and one mismatched.
936 {
937 MockRead data_reads[] = {
938 MockRead("HTTP/1.1 200 OK\r\n"),
939 MockRead("Content-Length: 10\r\n"),
940 MockRead("Content-Length: 10\r\n"),
941 MockRead("Content-Length: 5\r\n\r\n"),
942 };
943 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
944 arraysize(data_reads));
945 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
946 }
947}
948
[email protected]23e482282013-06-14 16:08:02949TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00950 MultipleContentLengthHeadersTransferEncoding) {
951 MockRead data_reads[] = {
952 MockRead("HTTP/1.1 200 OK\r\n"),
953 MockRead("Content-Length: 666\r\n"),
954 MockRead("Content-Length: 1337\r\n"),
955 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
956 MockRead("5\r\nHello\r\n"),
957 MockRead("1\r\n"),
958 MockRead(" \r\n"),
959 MockRead("5\r\nworld\r\n"),
960 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06961 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00962 };
963 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
964 arraysize(data_reads));
965 EXPECT_EQ(OK, out.rv);
966 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
967 EXPECT_EQ("Hello world", out.response_data);
968}
969
[email protected]1628fe92011-10-04 23:04:55970// Next tests deal with http://crbug.com/98895.
971
972// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02973TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55974 MockRead data_reads[] = {
975 MockRead("HTTP/1.1 200 OK\r\n"),
976 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
977 MockRead("Content-Length: 5\r\n\r\n"),
978 MockRead("Hello"),
979 };
980 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
981 arraysize(data_reads));
982 EXPECT_EQ(OK, out.rv);
983 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
984 EXPECT_EQ("Hello", out.response_data);
985}
986
[email protected]54a9c6e52012-03-21 20:10:59987// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02988TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59989 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55990 MockRead data_reads[] = {
991 MockRead("HTTP/1.1 200 OK\r\n"),
992 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
993 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
994 MockRead("Content-Length: 5\r\n\r\n"),
995 MockRead("Hello"),
996 };
997 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
998 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59999 EXPECT_EQ(OK, out.rv);
1000 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1001 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551002}
1003
1004// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:021005TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551006 MockRead data_reads[] = {
1007 MockRead("HTTP/1.1 200 OK\r\n"),
1008 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1009 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1010 MockRead("Content-Length: 5\r\n\r\n"),
1011 MockRead("Hello"),
1012 };
1013 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1014 arraysize(data_reads));
1015 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
1016}
1017
[email protected]54a9c6e52012-03-21 20:10:591018// Checks that two identical Location headers result in no error.
1019// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:021020TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551021 MockRead data_reads[] = {
1022 MockRead("HTTP/1.1 302 Redirect\r\n"),
1023 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591024 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551025 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061026 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551027 };
1028
1029 HttpRequestInfo request;
1030 request.method = "GET";
1031 request.url = GURL("http://redirect.com/");
1032 request.load_flags = 0;
1033
mmenkee65e7af2015-10-13 17:16:421034 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:551035 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411036 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:551037
1038 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071039 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551040
[email protected]49639fa2011-12-20 23:22:411041 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551042
[email protected]49639fa2011-12-20 23:22:411043 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:551044 EXPECT_EQ(ERR_IO_PENDING, rv);
1045
1046 EXPECT_EQ(OK, callback.WaitForResult());
1047
1048 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:501049 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:551050 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1051 std::string url;
1052 EXPECT_TRUE(response->headers->IsRedirect(&url));
1053 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151054 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551055}
1056
[email protected]1628fe92011-10-04 23:04:551057// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021058TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551059 MockRead data_reads[] = {
1060 MockRead("HTTP/1.1 302 Redirect\r\n"),
1061 MockRead("Location: http://good.com/\r\n"),
1062 MockRead("Location: http://evil.com/\r\n"),
1063 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061064 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551065 };
1066 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1067 arraysize(data_reads));
1068 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1069}
1070
[email protected]ef0faf2e72009-03-05 23:27:231071// Do a request using the HEAD method. Verify that we don't try to read the
1072// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021073TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421074 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231075 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231076 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231077 request.load_flags = 0;
1078
mmenkee65e7af2015-10-13 17:16:421079 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271080 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411081 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271082 BeforeProxyHeadersSentHandler proxy_headers_handler;
1083 trans->SetBeforeProxyHeadersSentCallback(
1084 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1085 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271086
[email protected]ef0faf2e72009-03-05 23:27:231087 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131088 MockWrite("HEAD / HTTP/1.1\r\n"
1089 "Host: www.example.org\r\n"
1090 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231091 };
1092 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231093 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1094 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231095
mmenked39192ee2015-12-09 00:57:231096 // No response body because the test stops reading here.
1097 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231098 };
1099
[email protected]31a2bfe2010-02-09 08:03:391100 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1101 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071102 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231103
[email protected]49639fa2011-12-20 23:22:411104 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231105
[email protected]49639fa2011-12-20 23:22:411106 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421107 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231108
1109 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421110 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231111
[email protected]1c773ea12009-04-28 19:58:421112 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501113 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231114
1115 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501116 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231117 EXPECT_EQ(1234, response->headers->GetContentLength());
1118 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151119 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271120 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231121
1122 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101123 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231124 bool has_server_header = response->headers->EnumerateHeader(
1125 &iter, "Server", &server_header);
1126 EXPECT_TRUE(has_server_header);
1127 EXPECT_EQ("Blah", server_header);
1128
1129 // Reading should give EOF right away, since there is no message body
1130 // (despite non-zero content-length).
1131 std::string response_data;
1132 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421133 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231134 EXPECT_EQ("", response_data);
1135}
1136
[email protected]23e482282013-06-14 16:08:021137TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
mmenkee65e7af2015-10-13 17:16:421138 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521139
1140 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351141 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1142 MockRead("hello"),
1143 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1144 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061145 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521146 };
[email protected]31a2bfe2010-02-09 08:03:391147 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071148 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521149
[email protected]0b0bf032010-09-21 18:08:501150 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521151 "hello", "world"
1152 };
1153
1154 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421155 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521156 request.method = "GET";
bncce36dca22015-04-21 22:11:231157 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521158 request.load_flags = 0;
1159
[email protected]262eec82013-03-19 21:01:361160 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501161 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271162
[email protected]49639fa2011-12-20 23:22:411163 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521164
[email protected]49639fa2011-12-20 23:22:411165 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421166 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521167
1168 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421169 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521170
[email protected]1c773ea12009-04-28 19:58:421171 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501172 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521173
[email protected]90499482013-06-01 00:39:501174 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251175 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151176 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521177
1178 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571179 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421180 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251181 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521182 }
1183}
1184
[email protected]23e482282013-06-14 16:08:021185TEST_P(HttpNetworkTransactionTest, Ignores100) {
olli.raula6df48b2a2015-11-26 07:40:221186 std::vector<scoped_ptr<UploadElementReader>> element_readers;
1187 element_readers.push_back(
1188 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
1189 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271190
[email protected]1c773ea12009-04-28 19:58:421191 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521192 request.method = "POST";
1193 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271194 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521195 request.load_flags = 0;
1196
mmenkee65e7af2015-10-13 17:16:421197 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271198 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271200
initial.commit586acc5fe2008-07-26 22:42:521201 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351202 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1203 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1204 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061205 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521206 };
[email protected]31a2bfe2010-02-09 08:03:391207 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071208 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521209
[email protected]49639fa2011-12-20 23:22:411210 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521211
[email protected]49639fa2011-12-20 23:22:411212 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421213 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521214
1215 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421216 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521217
[email protected]1c773ea12009-04-28 19:58:421218 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501219 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521220
[email protected]90499482013-06-01 00:39:501221 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251222 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521223
1224 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571225 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421226 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251227 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521228}
1229
[email protected]3a2d3662009-03-27 03:49:141230// This test is almost the same as Ignores100 above, but the response contains
1231// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571232// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021233TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421234 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141235 request.method = "GET";
1236 request.url = GURL("http://www.foo.com/");
1237 request.load_flags = 0;
1238
mmenkee65e7af2015-10-13 17:16:421239 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271240 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411241 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271242
[email protected]3a2d3662009-03-27 03:49:141243 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571244 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1245 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141246 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061247 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141248 };
[email protected]31a2bfe2010-02-09 08:03:391249 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071250 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141251
[email protected]49639fa2011-12-20 23:22:411252 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141253
[email protected]49639fa2011-12-20 23:22:411254 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421255 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141256
1257 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421258 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141259
[email protected]1c773ea12009-04-28 19:58:421260 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501261 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141262
[email protected]90499482013-06-01 00:39:501263 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141264 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1265
1266 std::string response_data;
1267 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421268 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141269 EXPECT_EQ("hello world", response_data);
1270}
1271
[email protected]23e482282013-06-14 16:08:021272TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081273 HttpRequestInfo request;
1274 request.method = "POST";
1275 request.url = GURL("http://www.foo.com/");
1276 request.load_flags = 0;
1277
mmenkee65e7af2015-10-13 17:16:421278 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
zmo9528c9f42015-08-04 22:12:081279 scoped_ptr<HttpTransaction> trans(
1280 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1281
1282 MockRead data_reads[] = {
1283 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1284 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381285 };
zmo9528c9f42015-08-04 22:12:081286 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1287 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381288
zmo9528c9f42015-08-04 22:12:081289 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381290
zmo9528c9f42015-08-04 22:12:081291 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1292 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381293
zmo9528c9f42015-08-04 22:12:081294 rv = callback.WaitForResult();
1295 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381296
zmo9528c9f42015-08-04 22:12:081297 std::string response_data;
1298 rv = ReadTransaction(trans.get(), &response_data);
1299 EXPECT_EQ(OK, rv);
1300 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381301}
1302
[email protected]23e482282013-06-14 16:08:021303TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381304 HttpRequestInfo request;
1305 request.method = "POST";
1306 request.url = GURL("http://www.foo.com/");
1307 request.load_flags = 0;
1308
mmenkee65e7af2015-10-13 17:16:421309 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271310 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271312
[email protected]ee9410e72010-01-07 01:42:381313 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061314 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381315 };
[email protected]31a2bfe2010-02-09 08:03:391316 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071317 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381318
[email protected]49639fa2011-12-20 23:22:411319 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381320
[email protected]49639fa2011-12-20 23:22:411321 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381322 EXPECT_EQ(ERR_IO_PENDING, rv);
1323
1324 rv = callback.WaitForResult();
1325 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1326}
1327
[email protected]23e482282013-06-14 16:08:021328void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511329 const MockWrite* write_failure,
1330 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421331 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521332 request.method = "GET";
1333 request.url = GURL("http://www.foo.com/");
1334 request.load_flags = 0;
1335
vishal.b62985ca92015-04-17 08:45:511336 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071337 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:421338 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271339
[email protected]202965992011-12-07 23:04:511340 // Written data for successfully sending both requests.
1341 MockWrite data1_writes[] = {
1342 MockWrite("GET / HTTP/1.1\r\n"
1343 "Host: www.foo.com\r\n"
1344 "Connection: keep-alive\r\n\r\n"),
1345 MockWrite("GET / HTTP/1.1\r\n"
1346 "Host: www.foo.com\r\n"
1347 "Connection: keep-alive\r\n\r\n")
1348 };
1349
1350 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521351 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351352 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1353 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061354 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521355 };
[email protected]202965992011-12-07 23:04:511356
1357 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491358 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511359 data1_writes[1] = *write_failure;
1360 } else {
1361 ASSERT_TRUE(read_failure);
1362 data1_reads[2] = *read_failure;
1363 }
1364
1365 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1366 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071367 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521368
1369 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351370 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1371 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061372 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521373 };
[email protected]31a2bfe2010-02-09 08:03:391374 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071375 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521376
thestig9d3bb0c2015-01-24 00:49:511377 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521378 "hello", "world"
1379 };
1380
avibf0746c2015-12-09 19:53:141381 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521382 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411383 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521384
[email protected]262eec82013-03-19 21:01:361385 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501386 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521387
[email protected]49639fa2011-12-20 23:22:411388 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421389 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521390
1391 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421392 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521393
[email protected]58e32bb2013-01-21 18:23:251394 LoadTimingInfo load_timing_info;
1395 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1396 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1397 if (i == 0) {
1398 first_socket_log_id = load_timing_info.socket_log_id;
1399 } else {
1400 // The second request should be using a new socket.
1401 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1402 }
1403
[email protected]1c773ea12009-04-28 19:58:421404 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501405 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521406
[email protected]90499482013-06-01 00:39:501407 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251408 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521409
1410 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571411 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421412 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251413 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521414 }
1415}
[email protected]3d2a59b2008-09-26 19:44:251416
[email protected]a34f61ee2014-03-18 20:59:491417void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1418 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101419 const MockRead* read_failure,
1420 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491421 HttpRequestInfo request;
1422 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101423 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491424 request.load_flags = 0;
1425
vishal.b62985ca92015-04-17 08:45:511426 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491427 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:421428 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491429
[email protected]09356c652014-03-25 15:36:101430 SSLSocketDataProvider ssl1(ASYNC, OK);
1431 SSLSocketDataProvider ssl2(ASYNC, OK);
1432 if (use_spdy) {
rdsmithebb50aa2015-11-12 03:44:381433 ssl1.SetNextProto(GetProtocol());
1434 ssl2.SetNextProto(GetProtocol());
[email protected]09356c652014-03-25 15:36:101435 }
1436 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1437 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491438
[email protected]09356c652014-03-25 15:36:101439 // SPDY versions of the request and response.
bncb03b1092016-04-06 11:19:551440 scoped_ptr<SpdySerializedFrame> spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491441 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
bncb03b1092016-04-06 11:19:551442 scoped_ptr<SpdySerializedFrame> spdy_response(
[email protected]09356c652014-03-25 15:36:101443 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
bncb03b1092016-04-06 11:19:551444 scoped_ptr<SpdySerializedFrame> spdy_data(
[email protected]09356c652014-03-25 15:36:101445 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491446
[email protected]09356c652014-03-25 15:36:101447 // HTTP/1.1 versions of the request and response.
1448 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1449 "Host: www.foo.com\r\n"
1450 "Connection: keep-alive\r\n\r\n";
1451 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1452 const char kHttpData[] = "hello";
1453
1454 std::vector<MockRead> data1_reads;
1455 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491456 if (write_failure) {
1457 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101458 data1_writes.push_back(*write_failure);
1459 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491460 } else {
1461 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101462 if (use_spdy) {
1463 data1_writes.push_back(CreateMockWrite(*spdy_request));
1464 } else {
1465 data1_writes.push_back(MockWrite(kHttpRequest));
1466 }
1467 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491468 }
1469
[email protected]09356c652014-03-25 15:36:101470 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1471 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491472 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1473
[email protected]09356c652014-03-25 15:36:101474 std::vector<MockRead> data2_reads;
1475 std::vector<MockWrite> data2_writes;
1476
1477 if (use_spdy) {
1478 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1479
1480 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1481 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1482 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1483 } else {
1484 data2_writes.push_back(
1485 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1486
1487 data2_reads.push_back(
1488 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1489 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1490 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1491 }
rch8e6c6c42015-05-01 14:05:131492 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1493 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491494 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1495
1496 // Preconnect a socket.
ttuttle859dc7a2015-04-23 19:42:291497 SSLConfig ssl_config;
[email protected]a34f61ee2014-03-18 20:59:491498 session->ssl_config_service()->GetSSLConfig(&ssl_config);
bnc1f295372015-10-21 23:24:221499 session->GetAlpnProtos(&ssl_config.alpn_protos);
1500 session->GetNpnProtos(&ssl_config.npn_protos);
mmenked1205bd2015-07-15 22:26:351501 session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
1502 ssl_config);
[email protected]a34f61ee2014-03-18 20:59:491503 // Wait for the preconnect to complete.
1504 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1505 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101506 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491507
1508 // Make the request.
1509 TestCompletionCallback callback;
1510
1511 scoped_ptr<HttpTransaction> trans(
1512 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1513
1514 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1515 EXPECT_EQ(ERR_IO_PENDING, rv);
1516
1517 rv = callback.WaitForResult();
1518 EXPECT_EQ(OK, rv);
1519
1520 LoadTimingInfo load_timing_info;
1521 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101522 TestLoadTimingNotReused(
1523 load_timing_info,
1524 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491525
1526 const HttpResponseInfo* response = trans->GetResponseInfo();
1527 ASSERT_TRUE(response != NULL);
1528
1529 EXPECT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:021530 if (response->was_fetched_via_spdy) {
1531 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1532 } else {
1533 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1534 }
[email protected]a34f61ee2014-03-18 20:59:491535
1536 std::string response_data;
1537 rv = ReadTransaction(trans.get(), &response_data);
1538 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101539 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491540}
1541
[email protected]23e482282013-06-14 16:08:021542TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231543 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061544 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511545 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1546}
1547
[email protected]23e482282013-06-14 16:08:021548TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061549 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511550 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251551}
1552
[email protected]23e482282013-06-14 16:08:021553TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061554 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511555 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251556}
1557
[email protected]d58ceea82014-06-04 10:55:541558// Make sure that on a 408 response (Request Timeout), the request is retried,
1559// if the socket was a reused keep alive socket.
1560TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1561 MockRead read_failure(SYNCHRONOUS,
1562 "HTTP/1.1 408 Request Timeout\r\n"
1563 "Connection: Keep-Alive\r\n"
1564 "Content-Length: 6\r\n\r\n"
1565 "Pickle");
1566 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1567}
1568
[email protected]a34f61ee2014-03-18 20:59:491569TEST_P(HttpNetworkTransactionTest,
1570 PreconnectErrorNotConnectedOnWrite) {
1571 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101572 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491573}
1574
1575TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1576 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101577 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491578}
1579
1580TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1581 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101582 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1583}
1584
1585TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1586 MockRead read_failure(ASYNC, OK); // EOF
1587 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1588}
1589
[email protected]d58ceea82014-06-04 10:55:541590// Make sure that on a 408 response (Request Timeout), the request is retried,
1591// if the socket was a preconnected (UNUSED_IDLE) socket.
1592TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1593 MockRead read_failure(SYNCHRONOUS,
1594 "HTTP/1.1 408 Request Timeout\r\n"
1595 "Connection: Keep-Alive\r\n"
1596 "Content-Length: 6\r\n\r\n"
1597 "Pickle");
1598 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1599 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1600}
1601
[email protected]09356c652014-03-25 15:36:101602TEST_P(HttpNetworkTransactionTest,
1603 SpdyPreconnectErrorNotConnectedOnWrite) {
1604 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1605 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1606}
1607
1608TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1609 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1610 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1611}
1612
1613TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1614 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1615 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1616}
1617
1618TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1619 MockRead read_failure(ASYNC, OK); // EOF
1620 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491621}
1622
[email protected]23e482282013-06-14 16:08:021623TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421624 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251625 request.method = "GET";
bncce36dca22015-04-21 22:11:231626 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251627 request.load_flags = 0;
1628
mmenkee65e7af2015-10-13 17:16:421629 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271630 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411631 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271632
[email protected]3d2a59b2008-09-26 19:44:251633 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061634 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351635 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1636 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061637 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251638 };
[email protected]31a2bfe2010-02-09 08:03:391639 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071640 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251641
[email protected]49639fa2011-12-20 23:22:411642 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251643
[email protected]49639fa2011-12-20 23:22:411644 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421645 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251646
1647 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421648 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:591649
1650 IPEndPoint endpoint;
1651 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
1652 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251653}
1654
1655// What do various browsers do when the server closes a non-keepalive
1656// connection without sending any response header or body?
1657//
1658// IE7: error page
1659// Safari 3.1.2 (Windows): error page
1660// Firefox 3.0.1: blank page
1661// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421662// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1663// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021664TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251665 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061666 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351667 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1668 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061669 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251670 };
[email protected]31a2bfe2010-02-09 08:03:391671 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1672 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421673 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251674}
[email protected]038e9a32008-10-08 22:40:161675
[email protected]1826a402014-01-08 15:40:481676// Test that network access can be deferred and resumed.
1677TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1678 HttpRequestInfo request;
1679 request.method = "GET";
bncce36dca22015-04-21 22:11:231680 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481681 request.load_flags = 0;
1682
mmenkee65e7af2015-10-13 17:16:421683 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481684 scoped_ptr<HttpTransaction> trans(
1685 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1686
1687 // Defer on OnBeforeNetworkStart.
1688 BeforeNetworkStartHandler net_start_handler(true); // defer
1689 trans->SetBeforeNetworkStartCallback(
1690 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1691 base::Unretained(&net_start_handler)));
1692
1693 MockRead data_reads[] = {
1694 MockRead("HTTP/1.0 200 OK\r\n"),
1695 MockRead("Content-Length: 5\r\n\r\n"),
1696 MockRead("hello"),
1697 MockRead(SYNCHRONOUS, 0),
1698 };
1699 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1700 session_deps_.socket_factory->AddSocketDataProvider(&data);
1701
1702 TestCompletionCallback callback;
1703
1704 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1705 EXPECT_EQ(ERR_IO_PENDING, rv);
1706 base::MessageLoop::current()->RunUntilIdle();
1707
1708 // Should have deferred for network start.
1709 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1710 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481711
1712 trans->ResumeNetworkStart();
1713 rv = callback.WaitForResult();
1714 EXPECT_EQ(OK, rv);
1715 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1716
1717 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1718 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1719 if (rv == ERR_IO_PENDING)
1720 rv = callback.WaitForResult();
1721 EXPECT_EQ(5, rv);
1722 trans.reset();
1723}
1724
1725// Test that network use can be deferred and canceled.
1726TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1727 HttpRequestInfo request;
1728 request.method = "GET";
bncce36dca22015-04-21 22:11:231729 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481730 request.load_flags = 0;
1731
mmenkee65e7af2015-10-13 17:16:421732 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1826a402014-01-08 15:40:481733 scoped_ptr<HttpTransaction> trans(
1734 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1735
1736 // Defer on OnBeforeNetworkStart.
1737 BeforeNetworkStartHandler net_start_handler(true); // defer
1738 trans->SetBeforeNetworkStartCallback(
1739 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1740 base::Unretained(&net_start_handler)));
1741
1742 TestCompletionCallback callback;
1743
1744 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1745 EXPECT_EQ(ERR_IO_PENDING, rv);
1746 base::MessageLoop::current()->RunUntilIdle();
1747
1748 // Should have deferred for network start.
1749 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1750 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481751}
1752
[email protected]7a5378b2012-11-04 03:25:171753// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1754// tests. There was a bug causing HttpNetworkTransaction to hang in the
1755// destructor in such situations.
1756// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021757TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171758 HttpRequestInfo request;
1759 request.method = "GET";
bncce36dca22015-04-21 22:11:231760 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171761 request.load_flags = 0;
1762
mmenkee65e7af2015-10-13 17:16:421763 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361764 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501765 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171766
1767 MockRead data_reads[] = {
1768 MockRead("HTTP/1.0 200 OK\r\n"),
1769 MockRead("Connection: keep-alive\r\n"),
1770 MockRead("Content-Length: 100\r\n\r\n"),
1771 MockRead("hello"),
1772 MockRead(SYNCHRONOUS, 0),
1773 };
1774 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071775 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171776
1777 TestCompletionCallback callback;
1778
1779 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1780 EXPECT_EQ(ERR_IO_PENDING, rv);
1781
1782 rv = callback.WaitForResult();
1783 EXPECT_EQ(OK, rv);
1784
1785 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501786 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171787 if (rv == ERR_IO_PENDING)
1788 rv = callback.WaitForResult();
1789 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501790 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171791 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1792
1793 trans.reset();
[email protected]2da659e2013-05-23 20:51:341794 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171795 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1796}
1797
[email protected]23e482282013-06-14 16:08:021798TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171799 HttpRequestInfo request;
1800 request.method = "GET";
bncce36dca22015-04-21 22:11:231801 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171802 request.load_flags = 0;
1803
mmenkee65e7af2015-10-13 17:16:421804 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361805 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501806 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171807
1808 MockRead data_reads[] = {
1809 MockRead("HTTP/1.0 200 OK\r\n"),
1810 MockRead("Connection: keep-alive\r\n"),
1811 MockRead("Content-Length: 100\r\n\r\n"),
1812 MockRead(SYNCHRONOUS, 0),
1813 };
1814 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071815 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171816
1817 TestCompletionCallback callback;
1818
1819 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1820 EXPECT_EQ(ERR_IO_PENDING, rv);
1821
1822 rv = callback.WaitForResult();
1823 EXPECT_EQ(OK, rv);
1824
1825 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501826 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171827 if (rv == ERR_IO_PENDING)
1828 rv = callback.WaitForResult();
1829 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1830
1831 trans.reset();
[email protected]2da659e2013-05-23 20:51:341832 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171833 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1834}
1835
[email protected]0b0bf032010-09-21 18:08:501836// Test that we correctly reuse a keep-alive connection after not explicitly
1837// reading the body.
[email protected]23e482282013-06-14 16:08:021838TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131839 HttpRequestInfo request;
1840 request.method = "GET";
1841 request.url = GURL("http://www.foo.com/");
1842 request.load_flags = 0;
1843
vishal.b62985ca92015-04-17 08:45:511844 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071845 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:421846 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271847
mmenkecc2298e2015-12-07 18:20:181848 const char* request_data =
1849 "GET / HTTP/1.1\r\n"
1850 "Host: www.foo.com\r\n"
1851 "Connection: keep-alive\r\n\r\n";
1852 MockWrite data_writes[] = {
1853 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1854 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1855 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1856 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1857 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1858 };
1859
[email protected]0b0bf032010-09-21 18:08:501860 // Note that because all these reads happen in the same
1861 // StaticSocketDataProvider, it shows that the same socket is being reused for
1862 // all transactions.
mmenkecc2298e2015-12-07 18:20:181863 MockRead data_reads[] = {
1864 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1865 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1866 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1867 MockRead(ASYNC, 7,
1868 "HTTP/1.1 302 Found\r\n"
1869 "Content-Length: 0\r\n\r\n"),
1870 MockRead(ASYNC, 9,
1871 "HTTP/1.1 302 Found\r\n"
1872 "Content-Length: 5\r\n\r\n"
1873 "hello"),
1874 MockRead(ASYNC, 11,
1875 "HTTP/1.1 301 Moved Permanently\r\n"
1876 "Content-Length: 0\r\n\r\n"),
1877 MockRead(ASYNC, 13,
1878 "HTTP/1.1 301 Moved Permanently\r\n"
1879 "Content-Length: 5\r\n\r\n"
1880 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131881
mmenkecc2298e2015-12-07 18:20:181882 // In the next two rounds, IsConnectedAndIdle returns false, due to
1883 // the set_busy_before_sync_reads(true) call, while the
1884 // HttpNetworkTransaction is being shut down, but the socket is still
1885 // reuseable. See http://crbug.com/544255.
1886 MockRead(ASYNC, 15,
1887 "HTTP/1.1 200 Hunky-Dory\r\n"
1888 "Content-Length: 5\r\n\r\n"),
1889 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131890
mmenkecc2298e2015-12-07 18:20:181891 MockRead(ASYNC, 18,
1892 "HTTP/1.1 200 Hunky-Dory\r\n"
1893 "Content-Length: 5\r\n\r\n"
1894 "he"),
1895 MockRead(SYNCHRONOUS, 19, "llo"),
1896
1897 // The body of the final request is actually read.
1898 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1899 MockRead(ASYNC, 22, "hello"),
1900 };
1901 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1902 arraysize(data_writes));
1903 data.set_busy_before_sync_reads(true);
1904 session_deps_.socket_factory->AddSocketDataProvider(&data);
1905
1906 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501907 std::string response_lines[kNumUnreadBodies];
1908
avibf0746c2015-12-09 19:53:141909 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181910 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411911 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131912
[email protected]262eec82013-03-19 21:01:361913 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501914 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131915
[email protected]49639fa2011-12-20 23:22:411916 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
mmenkecc2298e2015-12-07 18:20:181917 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]fc31d6a42010-06-24 18:05:131918
[email protected]58e32bb2013-01-21 18:23:251919 LoadTimingInfo load_timing_info;
1920 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1921 if (i == 0) {
1922 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1923 first_socket_log_id = load_timing_info.socket_log_id;
1924 } else {
1925 TestLoadTimingReused(load_timing_info);
1926 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1927 }
1928
[email protected]fc31d6a42010-06-24 18:05:131929 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181930 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131931
mmenkecc2298e2015-12-07 18:20:181932 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501933 response_lines[i] = response->headers->GetStatusLine();
1934
mmenkecc2298e2015-12-07 18:20:181935 // Delete the transaction without reading the response bodies. Then spin
1936 // the message loop, so the response bodies are drained.
1937 trans.reset();
1938 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131939 }
[email protected]0b0bf032010-09-21 18:08:501940
1941 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181942 "HTTP/1.1 204 No Content",
1943 "HTTP/1.1 205 Reset Content",
1944 "HTTP/1.1 304 Not Modified",
1945 "HTTP/1.1 302 Found",
1946 "HTTP/1.1 302 Found",
1947 "HTTP/1.1 301 Moved Permanently",
1948 "HTTP/1.1 301 Moved Permanently",
1949 "HTTP/1.1 200 Hunky-Dory",
1950 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:501951 };
1952
mostynb91e0da982015-01-20 19:17:271953 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1954 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501955
1956 for (int i = 0; i < kNumUnreadBodies; ++i)
1957 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1958
[email protected]49639fa2011-12-20 23:22:411959 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361960 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501961 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411962 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
mmenkecc2298e2015-12-07 18:20:181963 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]0b0bf032010-09-21 18:08:501964 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181965 ASSERT_TRUE(response);
1966 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501967 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1968 std::string response_data;
1969 rv = ReadTransaction(trans.get(), &response_data);
1970 EXPECT_EQ(OK, rv);
1971 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131972}
1973
[email protected]038e9a32008-10-08 22:40:161974// Test the request-challenge-retry sequence for basic auth.
1975// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021976TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421977 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161978 request.method = "GET";
bncce36dca22015-04-21 22:11:231979 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161980 request.load_flags = 0;
1981
vishal.b62985ca92015-04-17 08:45:511982 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071983 session_deps_.net_log = &log;
mmenkee65e7af2015-10-13 17:16:421984 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271985 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411986 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271987
[email protected]f9ee6b52008-11-08 06:46:231988 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231989 MockWrite(
1990 "GET / HTTP/1.1\r\n"
1991 "Host: www.example.org\r\n"
1992 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231993 };
1994
[email protected]038e9a32008-10-08 22:40:161995 MockRead data_reads1[] = {
1996 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1997 // Give a couple authenticate options (only the middle one is actually
1998 // supported).
[email protected]22927ad2009-09-21 19:56:191999 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162000 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2001 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2002 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2003 // Large content-length -- won't matter, as connection will be reset.
2004 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062005 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162006 };
2007
2008 // After calling trans->RestartWithAuth(), this is the request we should
2009 // be issuing -- the final header line contains the credentials.
2010 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232011 MockWrite(
2012 "GET / HTTP/1.1\r\n"
2013 "Host: www.example.org\r\n"
2014 "Connection: keep-alive\r\n"
2015 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162016 };
2017
2018 // Lastly, the server responds with the actual content.
2019 MockRead data_reads2[] = {
2020 MockRead("HTTP/1.0 200 OK\r\n"),
2021 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2022 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062023 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162024 };
2025
[email protected]31a2bfe2010-02-09 08:03:392026 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2027 data_writes1, arraysize(data_writes1));
2028 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2029 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072030 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2031 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162032
[email protected]49639fa2011-12-20 23:22:412033 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162034
[email protected]49639fa2011-12-20 23:22:412035 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422036 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162037
2038 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422039 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162040
[email protected]58e32bb2013-01-21 18:23:252041 LoadTimingInfo load_timing_info1;
2042 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2043 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2044
sclittlefb249892015-09-10 21:33:222045 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2046 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2047 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:192048 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2049
[email protected]1c773ea12009-04-28 19:58:422050 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502051 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042052 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162053
[email protected]49639fa2011-12-20 23:22:412054 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162055
[email protected]49639fa2011-12-20 23:22:412056 rv = trans->RestartWithAuth(
2057 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422058 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162059
2060 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422061 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162062
[email protected]58e32bb2013-01-21 18:23:252063 LoadTimingInfo load_timing_info2;
2064 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2065 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2066 // The load timing after restart should have a new socket ID, and times after
2067 // those of the first load timing.
2068 EXPECT_LE(load_timing_info1.receive_headers_end,
2069 load_timing_info2.connect_timing.connect_start);
2070 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2071
sclittlefb249892015-09-10 21:33:222072 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2073 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2074 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
[email protected]b8015c42013-12-24 15:18:192075 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2076
[email protected]038e9a32008-10-08 22:40:162077 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502078 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:162079 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2080 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162081}
2082
ttuttled9dbc652015-09-29 20:00:592083// Test the request-challenge-retry sequence for basic auth.
2084// (basic auth is the easiest to mock, because it has no randomness).
2085TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
2086 HttpRequestInfo request;
2087 request.method = "GET";
2088 request.url = GURL("http://www.example.org/");
2089 request.load_flags = 0;
2090
2091 TestNetLog log;
2092 MockHostResolver* resolver = new MockHostResolver();
2093 session_deps_.net_log = &log;
2094 session_deps_.host_resolver.reset(resolver);
mmenkee65e7af2015-10-13 17:16:422095 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
ttuttled9dbc652015-09-29 20:00:592096 scoped_ptr<HttpTransaction> trans(
2097 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2098
2099 resolver->rules()->ClearRules();
2100 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2101
2102 MockWrite data_writes1[] = {
2103 MockWrite("GET / HTTP/1.1\r\n"
2104 "Host: www.example.org\r\n"
2105 "Connection: keep-alive\r\n\r\n"),
2106 };
2107
2108 MockRead data_reads1[] = {
2109 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2110 // Give a couple authenticate options (only the middle one is actually
2111 // supported).
2112 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2113 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2114 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2115 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2116 // Large content-length -- won't matter, as connection will be reset.
2117 MockRead("Content-Length: 10000\r\n\r\n"),
2118 MockRead(SYNCHRONOUS, ERR_FAILED),
2119 };
2120
2121 // After calling trans->RestartWithAuth(), this is the request we should
2122 // be issuing -- the final header line contains the credentials.
2123 MockWrite data_writes2[] = {
2124 MockWrite("GET / HTTP/1.1\r\n"
2125 "Host: www.example.org\r\n"
2126 "Connection: keep-alive\r\n"
2127 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2128 };
2129
2130 // Lastly, the server responds with the actual content.
2131 MockRead data_reads2[] = {
2132 MockRead("HTTP/1.0 200 OK\r\n"),
2133 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2134 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2135 };
2136
2137 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2138 data_writes1, arraysize(data_writes1));
2139 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2140 data_writes2, arraysize(data_writes2));
2141 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2142 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2143
2144 TestCompletionCallback callback1;
2145
2146 EXPECT_EQ(OK, callback1.GetResult(trans->Start(&request, callback1.callback(),
2147 BoundNetLog())));
2148
2149 LoadTimingInfo load_timing_info1;
2150 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2151 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2152
2153 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2154 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2155 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
2156 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2157
2158 const HttpResponseInfo* response = trans->GetResponseInfo();
2159 ASSERT_TRUE(response);
2160 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2161
2162 IPEndPoint endpoint;
2163 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2164 ASSERT_FALSE(endpoint.address().empty());
2165 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2166
2167 resolver->rules()->ClearRules();
2168 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2169
2170 TestCompletionCallback callback2;
2171
2172 EXPECT_EQ(OK, callback2.GetResult(trans->RestartWithAuth(
2173 AuthCredentials(kFoo, kBar), callback2.callback())));
2174
2175 LoadTimingInfo load_timing_info2;
2176 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2177 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2178 // The load timing after restart should have a new socket ID, and times after
2179 // those of the first load timing.
2180 EXPECT_LE(load_timing_info1.receive_headers_end,
2181 load_timing_info2.connect_timing.connect_start);
2182 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2183
2184 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2185 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2186 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
2187 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2188
2189 response = trans->GetResponseInfo();
2190 ASSERT_TRUE(response);
2191 EXPECT_FALSE(response->auth_challenge.get());
2192 EXPECT_EQ(100, response->headers->GetContentLength());
2193
2194 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2195 ASSERT_FALSE(endpoint.address().empty());
2196 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2197}
2198
[email protected]23e482282013-06-14 16:08:022199TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462200 HttpRequestInfo request;
2201 request.method = "GET";
bncce36dca22015-04-21 22:11:232202 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292203 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462204
mmenkee65e7af2015-10-13 17:16:422205 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272206 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412207 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272208
[email protected]861fcd52009-08-26 02:33:462209 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232210 MockWrite(
2211 "GET / HTTP/1.1\r\n"
2212 "Host: www.example.org\r\n"
2213 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462214 };
2215
2216 MockRead data_reads[] = {
2217 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2218 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2219 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2220 // Large content-length -- won't matter, as connection will be reset.
2221 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062222 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462223 };
2224
[email protected]31a2bfe2010-02-09 08:03:392225 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2226 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072227 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412228 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462229
[email protected]49639fa2011-12-20 23:22:412230 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462231 EXPECT_EQ(ERR_IO_PENDING, rv);
2232
2233 rv = callback.WaitForResult();
2234 EXPECT_EQ(0, rv);
2235
sclittlefb249892015-09-10 21:33:222236 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2237 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2238 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
[email protected]b8015c42013-12-24 15:18:192239 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2240
[email protected]861fcd52009-08-26 02:33:462241 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502242 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462243 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2244}
2245
[email protected]2d2697f92009-02-18 21:00:322246// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2247// connection.
[email protected]23e482282013-06-14 16:08:022248TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182249 // On the second pass, the body read of the auth challenge is synchronous, so
2250 // IsConnectedAndIdle returns false. The socket should still be drained and
2251 // reused. See http://crbug.com/544255.
2252 for (int i = 0; i < 2; ++i) {
2253 HttpRequestInfo request;
2254 request.method = "GET";
2255 request.url = GURL("http://www.example.org/");
2256 request.load_flags = 0;
[email protected]2d2697f92009-02-18 21:00:322257
mmenkecc2298e2015-12-07 18:20:182258 TestNetLog log;
2259 session_deps_.net_log = &log;
2260 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272261
mmenkecc2298e2015-12-07 18:20:182262 MockWrite data_writes[] = {
2263 MockWrite(ASYNC, 0,
2264 "GET / HTTP/1.1\r\n"
2265 "Host: www.example.org\r\n"
2266 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322267
mmenkecc2298e2015-12-07 18:20:182268 // After calling trans->RestartWithAuth(), this is the request we should
2269 // be issuing -- the final header line contains the credentials.
2270 MockWrite(ASYNC, 6,
2271 "GET / HTTP/1.1\r\n"
2272 "Host: www.example.org\r\n"
2273 "Connection: keep-alive\r\n"
2274 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2275 };
[email protected]2d2697f92009-02-18 21:00:322276
mmenkecc2298e2015-12-07 18:20:182277 MockRead data_reads[] = {
2278 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2279 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2280 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2281 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2282 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322283
mmenkecc2298e2015-12-07 18:20:182284 // Lastly, the server responds with the actual content.
2285 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2286 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2287 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2288 MockRead(ASYNC, 10, "Hello"),
2289 };
[email protected]2d2697f92009-02-18 21:00:322290
mmenkecc2298e2015-12-07 18:20:182291 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2292 arraysize(data_writes));
2293 data.set_busy_before_sync_reads(true);
2294 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462295
mmenkecc2298e2015-12-07 18:20:182296 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322297
mmenkecc2298e2015-12-07 18:20:182298 scoped_ptr<HttpTransaction> trans(
2299 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2300 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2301 ASSERT_EQ(OK, callback1.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:322302
mmenkecc2298e2015-12-07 18:20:182303 LoadTimingInfo load_timing_info1;
2304 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2305 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322306
mmenkecc2298e2015-12-07 18:20:182307 const HttpResponseInfo* response = trans->GetResponseInfo();
2308 ASSERT_TRUE(response);
2309 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322310
mmenkecc2298e2015-12-07 18:20:182311 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252312
mmenkecc2298e2015-12-07 18:20:182313 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
2314 callback2.callback());
2315 ASSERT_EQ(OK, callback2.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:322316
mmenkecc2298e2015-12-07 18:20:182317 LoadTimingInfo load_timing_info2;
2318 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2319 TestLoadTimingReused(load_timing_info2);
2320 // The load timing after restart should have the same socket ID, and times
2321 // those of the first load timing.
2322 EXPECT_LE(load_timing_info1.receive_headers_end,
2323 load_timing_info2.send_start);
2324 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322325
mmenkecc2298e2015-12-07 18:20:182326 response = trans->GetResponseInfo();
2327 ASSERT_TRUE(response);
2328 EXPECT_FALSE(response->auth_challenge);
2329 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322330
mmenkecc2298e2015-12-07 18:20:182331 std::string response_data;
2332 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]2d2697f92009-02-18 21:00:322333
mmenkecc2298e2015-12-07 18:20:182334 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2335 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2336 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
2337 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2338 }
[email protected]2d2697f92009-02-18 21:00:322339}
2340
2341// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2342// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022343TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422344 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322345 request.method = "GET";
bncce36dca22015-04-21 22:11:232346 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322347 request.load_flags = 0;
2348
mmenkee65e7af2015-10-13 17:16:422349 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272350
[email protected]2d2697f92009-02-18 21:00:322351 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232352 MockWrite(
2353 "GET / HTTP/1.1\r\n"
2354 "Host: www.example.org\r\n"
2355 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322356
bncce36dca22015-04-21 22:11:232357 // After calling trans->RestartWithAuth(), this is the request we should
2358 // be issuing -- the final header line contains the credentials.
2359 MockWrite(
2360 "GET / HTTP/1.1\r\n"
2361 "Host: www.example.org\r\n"
2362 "Connection: keep-alive\r\n"
2363 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322364 };
2365
[email protected]2d2697f92009-02-18 21:00:322366 MockRead data_reads1[] = {
2367 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2368 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312369 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322370
2371 // Lastly, the server responds with the actual content.
2372 MockRead("HTTP/1.1 200 OK\r\n"),
2373 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502374 MockRead("Content-Length: 5\r\n\r\n"),
2375 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322376 };
2377
[email protected]2d0a4f92011-05-05 16:38:462378 // An incorrect reconnect would cause this to be read.
2379 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062380 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462381 };
2382
[email protected]31a2bfe2010-02-09 08:03:392383 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2384 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462385 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2386 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072387 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2388 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322389
[email protected]49639fa2011-12-20 23:22:412390 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322391
[email protected]262eec82013-03-19 21:01:362392 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502393 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412394 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422395 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322396
2397 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422398 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322399
[email protected]1c773ea12009-04-28 19:58:422400 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502401 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042402 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322403
[email protected]49639fa2011-12-20 23:22:412404 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322405
[email protected]49639fa2011-12-20 23:22:412406 rv = trans->RestartWithAuth(
2407 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422408 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322409
2410 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422411 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322412
2413 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502414 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322415 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502416 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322417}
2418
2419// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2420// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022421TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422422 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322423 request.method = "GET";
bncce36dca22015-04-21 22:11:232424 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322425 request.load_flags = 0;
2426
mmenkee65e7af2015-10-13 17:16:422427 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272428
[email protected]2d2697f92009-02-18 21:00:322429 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232430 MockWrite(
2431 "GET / HTTP/1.1\r\n"
2432 "Host: www.example.org\r\n"
2433 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322434
bncce36dca22015-04-21 22:11:232435 // After calling trans->RestartWithAuth(), this is the request we should
2436 // be issuing -- the final header line contains the credentials.
2437 MockWrite(
2438 "GET / HTTP/1.1\r\n"
2439 "Host: www.example.org\r\n"
2440 "Connection: keep-alive\r\n"
2441 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322442 };
2443
2444 // Respond with 5 kb of response body.
2445 std::string large_body_string("Unauthorized");
2446 large_body_string.append(5 * 1024, ' ');
2447 large_body_string.append("\r\n");
2448
2449 MockRead data_reads1[] = {
2450 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2451 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2452 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2453 // 5134 = 12 + 5 * 1024 + 2
2454 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062455 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322456
2457 // Lastly, the server responds with the actual content.
2458 MockRead("HTTP/1.1 200 OK\r\n"),
2459 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502460 MockRead("Content-Length: 5\r\n\r\n"),
2461 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322462 };
2463
[email protected]2d0a4f92011-05-05 16:38:462464 // An incorrect reconnect would cause this to be read.
2465 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062466 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462467 };
2468
[email protected]31a2bfe2010-02-09 08:03:392469 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2470 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462471 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2472 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072473 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2474 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322475
[email protected]49639fa2011-12-20 23:22:412476 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322477
[email protected]262eec82013-03-19 21:01:362478 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502479 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412480 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422481 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322482
2483 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422484 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322485
[email protected]1c773ea12009-04-28 19:58:422486 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502487 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042488 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322489
[email protected]49639fa2011-12-20 23:22:412490 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322491
[email protected]49639fa2011-12-20 23:22:412492 rv = trans->RestartWithAuth(
2493 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422494 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322495
2496 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422497 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322498
2499 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502500 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322501 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502502 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322503}
2504
2505// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312506// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022507TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312508 HttpRequestInfo request;
2509 request.method = "GET";
bncce36dca22015-04-21 22:11:232510 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312511 request.load_flags = 0;
2512
mmenkee65e7af2015-10-13 17:16:422513 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272514
[email protected]11203f012009-11-12 23:02:312515 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232516 MockWrite(
2517 "GET / HTTP/1.1\r\n"
2518 "Host: www.example.org\r\n"
2519 "Connection: keep-alive\r\n\r\n"),
2520 // This simulates the seemingly successful write to a closed connection
2521 // if the bug is not fixed.
2522 MockWrite(
2523 "GET / HTTP/1.1\r\n"
2524 "Host: www.example.org\r\n"
2525 "Connection: keep-alive\r\n"
2526 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312527 };
2528
2529 MockRead data_reads1[] = {
2530 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2531 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2532 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2533 MockRead("Content-Length: 14\r\n\r\n"),
2534 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062535 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312536 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062537 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312538 };
2539
2540 // After calling trans->RestartWithAuth(), this is the request we should
2541 // be issuing -- the final header line contains the credentials.
2542 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232543 MockWrite(
2544 "GET / HTTP/1.1\r\n"
2545 "Host: www.example.org\r\n"
2546 "Connection: keep-alive\r\n"
2547 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312548 };
2549
2550 // Lastly, the server responds with the actual content.
2551 MockRead data_reads2[] = {
2552 MockRead("HTTP/1.1 200 OK\r\n"),
2553 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502554 MockRead("Content-Length: 5\r\n\r\n"),
2555 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312556 };
2557
[email protected]31a2bfe2010-02-09 08:03:392558 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2559 data_writes1, arraysize(data_writes1));
2560 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2561 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072562 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2563 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312564
[email protected]49639fa2011-12-20 23:22:412565 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312566
[email protected]262eec82013-03-19 21:01:362567 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502568 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412569 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312570 EXPECT_EQ(ERR_IO_PENDING, rv);
2571
2572 rv = callback1.WaitForResult();
2573 EXPECT_EQ(OK, rv);
2574
2575 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502576 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042577 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312578
[email protected]49639fa2011-12-20 23:22:412579 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312580
[email protected]49639fa2011-12-20 23:22:412581 rv = trans->RestartWithAuth(
2582 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312583 EXPECT_EQ(ERR_IO_PENDING, rv);
2584
2585 rv = callback2.WaitForResult();
2586 EXPECT_EQ(OK, rv);
2587
2588 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502589 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312590 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502591 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312592}
2593
[email protected]394816e92010-08-03 07:38:592594// Test the request-challenge-retry sequence for basic auth, over a connection
2595// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012596TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2597 HttpRequestInfo request;
2598 request.method = "GET";
bncce36dca22015-04-21 22:11:232599 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012600 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292601 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012602
2603 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032604 session_deps_.proxy_service =
2605 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512606 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012607 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422608 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012609
2610 // Since we have proxy, should try to establish tunnel.
2611 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542612 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172613 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542614 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012615 };
2616
mmenkee71e15332015-10-07 16:39:542617 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012618 // connection.
2619 MockRead data_reads1[] = {
2620 // No credentials.
2621 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2622 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542623 };
ttuttle34f63b52015-03-05 04:33:012624
mmenkee71e15332015-10-07 16:39:542625 // Since the first connection couldn't be reused, need to establish another
2626 // once given credentials.
2627 MockWrite data_writes2[] = {
2628 // After calling trans->RestartWithAuth(), this is the request we should
2629 // be issuing -- the final header line contains the credentials.
2630 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172631 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542632 "Proxy-Connection: keep-alive\r\n"
2633 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2634
2635 MockWrite("GET / HTTP/1.1\r\n"
2636 "Host: www.example.org\r\n"
2637 "Connection: keep-alive\r\n\r\n"),
2638 };
2639
2640 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012641 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2642
2643 MockRead("HTTP/1.1 200 OK\r\n"),
2644 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2645 MockRead("Content-Length: 5\r\n\r\n"),
2646 MockRead(SYNCHRONOUS, "hello"),
2647 };
2648
2649 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2650 data_writes1, arraysize(data_writes1));
2651 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542652 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2653 data_writes2, arraysize(data_writes2));
2654 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012655 SSLSocketDataProvider ssl(ASYNC, OK);
2656 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2657
2658 TestCompletionCallback callback1;
2659
2660 scoped_ptr<HttpTransaction> trans(
2661 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2662
2663 int rv = trans->Start(&request, callback1.callback(), log.bound());
2664 EXPECT_EQ(ERR_IO_PENDING, rv);
2665
2666 rv = callback1.WaitForResult();
2667 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462668 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012669 log.GetEntries(&entries);
2670 size_t pos = ExpectLogContainsSomewhere(
2671 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2672 NetLog::PHASE_NONE);
2673 ExpectLogContainsSomewhere(
2674 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2675 NetLog::PHASE_NONE);
2676
2677 const HttpResponseInfo* response = trans->GetResponseInfo();
2678 ASSERT_TRUE(response != NULL);
2679 EXPECT_FALSE(response->headers->IsKeepAlive());
2680 ASSERT_FALSE(response->headers.get() == NULL);
2681 EXPECT_EQ(407, response->headers->response_code());
2682 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2683 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2684
2685 LoadTimingInfo load_timing_info;
2686 // CONNECT requests and responses are handled at the connect job level, so
2687 // the transaction does not yet have a connection.
2688 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2689
2690 TestCompletionCallback callback2;
2691
2692 rv =
2693 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2694 EXPECT_EQ(ERR_IO_PENDING, rv);
2695
2696 rv = callback2.WaitForResult();
2697 EXPECT_EQ(OK, rv);
2698
2699 response = trans->GetResponseInfo();
2700 ASSERT_TRUE(response != NULL);
2701
2702 EXPECT_TRUE(response->headers->IsKeepAlive());
2703 EXPECT_EQ(200, response->headers->response_code());
2704 EXPECT_EQ(5, response->headers->GetContentLength());
2705 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2706
2707 // The password prompt info should not be set.
2708 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2709
2710 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2711 TestLoadTimingNotReusedWithPac(load_timing_info,
2712 CONNECT_TIMING_HAS_SSL_TIMES);
2713
2714 trans.reset();
2715 session->CloseAllConnections();
2716}
2717
2718// Test the request-challenge-retry sequence for basic auth, over a connection
2719// that requires a restart when setting up an SSL tunnel.
2720TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592721 HttpRequestInfo request;
2722 request.method = "GET";
bncce36dca22015-04-21 22:11:232723 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592724 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292725 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592726
[email protected]cb9bf6ca2011-01-28 13:15:272727 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032728 session_deps_.proxy_service =
2729 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512730 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072731 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:422732 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272733
[email protected]394816e92010-08-03 07:38:592734 // Since we have proxy, should try to establish tunnel.
2735 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542736 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172737 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542738 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112739 };
2740
mmenkee71e15332015-10-07 16:39:542741 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:082742 // connection.
2743 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:542744 // No credentials.
2745 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2746 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2747 MockRead("Proxy-Connection: close\r\n\r\n"),
2748 };
mmenkee0b5c882015-08-26 20:29:112749
mmenkee71e15332015-10-07 16:39:542750 MockWrite data_writes2[] = {
2751 // After calling trans->RestartWithAuth(), this is the request we should
2752 // be issuing -- the final header line contains the credentials.
2753 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172754 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542755 "Proxy-Connection: keep-alive\r\n"
2756 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:082757
mmenkee71e15332015-10-07 16:39:542758 MockWrite("GET / HTTP/1.1\r\n"
2759 "Host: www.example.org\r\n"
2760 "Connection: keep-alive\r\n\r\n"),
2761 };
2762
2763 MockRead data_reads2[] = {
2764 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2765
2766 MockRead("HTTP/1.1 200 OK\r\n"),
2767 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2768 MockRead("Content-Length: 5\r\n\r\n"),
2769 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592770 };
2771
2772 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2773 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072774 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542775 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2776 data_writes2, arraysize(data_writes2));
2777 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:062778 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592780
[email protected]49639fa2011-12-20 23:22:412781 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592782
[email protected]262eec82013-03-19 21:01:362783 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502784 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502785
[email protected]49639fa2011-12-20 23:22:412786 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592787 EXPECT_EQ(ERR_IO_PENDING, rv);
2788
2789 rv = callback1.WaitForResult();
2790 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462791 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402792 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592793 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402794 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592795 NetLog::PHASE_NONE);
2796 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402797 entries, pos,
[email protected]394816e92010-08-03 07:38:592798 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2799 NetLog::PHASE_NONE);
2800
2801 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502802 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012803 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502804 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592805 EXPECT_EQ(407, response->headers->response_code());
2806 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042807 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592808
[email protected]029c83b62013-01-24 05:28:202809 LoadTimingInfo load_timing_info;
2810 // CONNECT requests and responses are handled at the connect job level, so
2811 // the transaction does not yet have a connection.
2812 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2813
[email protected]49639fa2011-12-20 23:22:412814 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592815
[email protected]49639fa2011-12-20 23:22:412816 rv = trans->RestartWithAuth(
2817 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592818 EXPECT_EQ(ERR_IO_PENDING, rv);
2819
2820 rv = callback2.WaitForResult();
2821 EXPECT_EQ(OK, rv);
2822
2823 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502824 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592825
2826 EXPECT_TRUE(response->headers->IsKeepAlive());
2827 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502828 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592829 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2830
2831 // The password prompt info should not be set.
2832 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502833
[email protected]029c83b62013-01-24 05:28:202834 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2835 TestLoadTimingNotReusedWithPac(load_timing_info,
2836 CONNECT_TIMING_HAS_SSL_TIMES);
2837
[email protected]0b0bf032010-09-21 18:08:502838 trans.reset();
[email protected]102e27c2011-02-23 01:01:312839 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592840}
2841
[email protected]11203f012009-11-12 23:02:312842// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012843// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2844TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:232845 // On the second pass, the body read of the auth challenge is synchronous, so
2846 // IsConnectedAndIdle returns false. The socket should still be drained and
2847 // reused. See http://crbug.com/544255.
2848 for (int i = 0; i < 2; ++i) {
2849 HttpRequestInfo request;
2850 request.method = "GET";
2851 request.url = GURL("https://www.example.org/");
2852 // Ensure that proxy authentication is attempted even
2853 // when the no authentication data flag is set.
2854 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012855
mmenked39192ee2015-12-09 00:57:232856 // Configure against proxy server "myproxy:70".
2857 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
2858 BoundTestNetLog log;
2859 session_deps_.net_log = log.bound().net_log();
2860 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012861
mmenked39192ee2015-12-09 00:57:232862 scoped_ptr<HttpTransaction> trans(
2863 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ttuttle34f63b52015-03-05 04:33:012864
mmenked39192ee2015-12-09 00:57:232865 // Since we have proxy, should try to establish tunnel.
2866 MockWrite data_writes1[] = {
2867 MockWrite(ASYNC, 0,
2868 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2869 "Host: www.example.org:443\r\n"
2870 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012871
mmenked39192ee2015-12-09 00:57:232872 // After calling trans->RestartWithAuth(), this is the request we should
2873 // be issuing -- the final header line contains the credentials.
2874 MockWrite(ASYNC, 3,
2875 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2876 "Host: www.example.org:443\r\n"
2877 "Proxy-Connection: keep-alive\r\n"
2878 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2879 };
ttuttle34f63b52015-03-05 04:33:012880
mmenked39192ee2015-12-09 00:57:232881 // The proxy responds to the connect with a 407, using a persistent
2882 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2883 MockRead data_reads1[] = {
2884 // No credentials.
2885 MockRead(ASYNC, 1,
2886 "HTTP/1.0 407 Proxy Authentication Required\r\n"
2887 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
2888 "Proxy-Connection: keep-alive\r\n"
2889 "Content-Length: 10\r\n\r\n"),
2890 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:012891
mmenked39192ee2015-12-09 00:57:232892 // Wrong credentials (wrong password).
2893 MockRead(ASYNC, 4,
2894 "HTTP/1.0 407 Proxy Authentication Required\r\n"
2895 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
2896 "Proxy-Connection: keep-alive\r\n"
2897 "Content-Length: 10\r\n\r\n"),
2898 // No response body because the test stops reading here.
2899 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
2900 };
ttuttle34f63b52015-03-05 04:33:012901
mmenked39192ee2015-12-09 00:57:232902 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
2903 arraysize(data_writes1));
2904 data1.set_busy_before_sync_reads(true);
2905 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:012906
mmenked39192ee2015-12-09 00:57:232907 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:012908
mmenked39192ee2015-12-09 00:57:232909 int rv = trans->Start(&request, callback1.callback(), log.bound());
2910 EXPECT_EQ(OK, callback1.GetResult(rv));
ttuttle34f63b52015-03-05 04:33:012911
mmenked39192ee2015-12-09 00:57:232912 TestNetLogEntry::List entries;
2913 log.GetEntries(&entries);
2914 size_t pos = ExpectLogContainsSomewhere(
2915 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2916 NetLog::PHASE_NONE);
2917 ExpectLogContainsSomewhere(
2918 entries, pos,
2919 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2920 NetLog::PHASE_NONE);
ttuttle34f63b52015-03-05 04:33:012921
mmenked39192ee2015-12-09 00:57:232922 const HttpResponseInfo* response = trans->GetResponseInfo();
2923 ASSERT_TRUE(response);
2924 ASSERT_TRUE(response->headers);
2925 EXPECT_TRUE(response->headers->IsKeepAlive());
2926 EXPECT_EQ(407, response->headers->response_code());
2927 EXPECT_EQ(10, response->headers->GetContentLength());
2928 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2929 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:012930
mmenked39192ee2015-12-09 00:57:232931 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:012932
mmenked39192ee2015-12-09 00:57:232933 // Wrong password (should be "bar").
2934 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
2935 callback2.callback());
2936 EXPECT_EQ(OK, callback2.GetResult(rv));
ttuttle34f63b52015-03-05 04:33:012937
mmenked39192ee2015-12-09 00:57:232938 response = trans->GetResponseInfo();
2939 ASSERT_TRUE(response);
2940 ASSERT_TRUE(response->headers);
2941 EXPECT_TRUE(response->headers->IsKeepAlive());
2942 EXPECT_EQ(407, response->headers->response_code());
2943 EXPECT_EQ(10, response->headers->GetContentLength());
2944 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2945 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:012946
mmenked39192ee2015-12-09 00:57:232947 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2948 // out of scope.
2949 session->CloseAllConnections();
2950 }
ttuttle34f63b52015-03-05 04:33:012951}
2952
2953// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2954// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2955TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:232956 // On the second pass, the body read of the auth challenge is synchronous, so
2957 // IsConnectedAndIdle returns false. The socket should still be drained and
2958 // reused. See http://crbug.com/544255.
2959 for (int i = 0; i < 2; ++i) {
2960 HttpRequestInfo request;
2961 request.method = "GET";
2962 request.url = GURL("https://www.example.org/");
2963 // Ensure that proxy authentication is attempted even
2964 // when the no authentication data flag is set.
2965 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
2966
2967 // Configure against proxy server "myproxy:70".
2968 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
2969 BoundTestNetLog log;
2970 session_deps_.net_log = log.bound().net_log();
2971 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2972
2973 scoped_ptr<HttpTransaction> trans(
2974 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2975
2976 // Since we have proxy, should try to establish tunnel.
2977 MockWrite data_writes1[] = {
2978 MockWrite(ASYNC, 0,
2979 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2980 "Host: www.example.org:443\r\n"
2981 "Proxy-Connection: keep-alive\r\n\r\n"),
2982
2983 // After calling trans->RestartWithAuth(), this is the request we should
2984 // be issuing -- the final header line contains the credentials.
2985 MockWrite(ASYNC, 3,
2986 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2987 "Host: www.example.org:443\r\n"
2988 "Proxy-Connection: keep-alive\r\n"
2989 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2990 };
2991
2992 // The proxy responds to the connect with a 407, using a persistent
2993 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2994 MockRead data_reads1[] = {
2995 // No credentials.
2996 MockRead(ASYNC, 1,
2997 "HTTP/1.1 407 Proxy Authentication Required\r\n"
2998 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
2999 "Content-Length: 10\r\n\r\n"),
3000 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3001
3002 // Wrong credentials (wrong password).
3003 MockRead(ASYNC, 4,
3004 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3005 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3006 "Content-Length: 10\r\n\r\n"),
3007 // No response body because the test stops reading here.
3008 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3009 };
3010
3011 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3012 arraysize(data_writes1));
3013 data1.set_busy_before_sync_reads(true);
3014 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3015
3016 TestCompletionCallback callback1;
3017
3018 int rv = trans->Start(&request, callback1.callback(), log.bound());
3019 EXPECT_EQ(OK, callback1.GetResult(rv));
3020
3021 TestNetLogEntry::List entries;
3022 log.GetEntries(&entries);
3023 size_t pos = ExpectLogContainsSomewhere(
3024 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3025 NetLog::PHASE_NONE);
3026 ExpectLogContainsSomewhere(
3027 entries, pos,
3028 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3029 NetLog::PHASE_NONE);
3030
3031 const HttpResponseInfo* response = trans->GetResponseInfo();
3032 ASSERT_TRUE(response);
3033 ASSERT_TRUE(response->headers);
3034 EXPECT_TRUE(response->headers->IsKeepAlive());
3035 EXPECT_EQ(407, response->headers->response_code());
3036 EXPECT_EQ(10, response->headers->GetContentLength());
3037 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3038 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3039
3040 TestCompletionCallback callback2;
3041
3042 // Wrong password (should be "bar").
3043 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
3044 callback2.callback());
3045 EXPECT_EQ(OK, callback2.GetResult(rv));
3046
3047 response = trans->GetResponseInfo();
3048 ASSERT_TRUE(response);
3049 ASSERT_TRUE(response->headers);
3050 EXPECT_TRUE(response->headers->IsKeepAlive());
3051 EXPECT_EQ(407, response->headers->response_code());
3052 EXPECT_EQ(10, response->headers->GetContentLength());
3053 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3054 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3055
3056 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3057 // out of scope.
3058 session->CloseAllConnections();
3059 }
3060}
3061
3062// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3063// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3064// the case the server sends extra data on the original socket, so it can't be
3065// reused.
3066TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273067 HttpRequestInfo request;
3068 request.method = "GET";
bncce36dca22015-04-21 22:11:233069 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273070 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293071 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273072
[email protected]2d2697f92009-02-18 21:00:323073 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233074 session_deps_.proxy_service =
3075 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513076 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073077 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423078 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323079
[email protected]2d2697f92009-02-18 21:00:323080 // Since we have proxy, should try to establish tunnel.
3081 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233082 MockWrite(ASYNC, 0,
3083 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173084 "Host: www.example.org:443\r\n"
3085 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233086 };
[email protected]2d2697f92009-02-18 21:00:323087
mmenked39192ee2015-12-09 00:57:233088 // The proxy responds to the connect with a 407, using a persistent, but sends
3089 // extra data, so the socket cannot be reused.
3090 MockRead data_reads1[] = {
3091 // No credentials.
3092 MockRead(ASYNC, 1,
3093 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3094 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3095 "Content-Length: 10\r\n\r\n"),
3096 MockRead(SYNCHRONOUS, 2, "0123456789"),
3097 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3098 };
3099
3100 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233101 // After calling trans->RestartWithAuth(), this is the request we should
3102 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233103 MockWrite(ASYNC, 0,
3104 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173105 "Host: www.example.org:443\r\n"
3106 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233107 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3108
3109 MockWrite(ASYNC, 2,
3110 "GET / HTTP/1.1\r\n"
3111 "Host: www.example.org\r\n"
3112 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323113 };
3114
mmenked39192ee2015-12-09 00:57:233115 MockRead data_reads2[] = {
3116 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323117
mmenked39192ee2015-12-09 00:57:233118 MockRead(ASYNC, 3,
3119 "HTTP/1.1 200 OK\r\n"
3120 "Content-Type: text/html; charset=iso-8859-1\r\n"
3121 "Content-Length: 5\r\n\r\n"),
3122 // No response body because the test stops reading here.
3123 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323124 };
3125
mmenked39192ee2015-12-09 00:57:233126 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3127 arraysize(data_writes1));
3128 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073129 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233130 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3131 arraysize(data_writes2));
3132 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3133 SSLSocketDataProvider ssl(ASYNC, OK);
3134 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323135
[email protected]49639fa2011-12-20 23:22:413136 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323137
mmenked39192ee2015-12-09 00:57:233138 scoped_ptr<HttpTransaction> trans(
3139 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:323140
mmenked39192ee2015-12-09 00:57:233141 int rv = trans->Start(&request, callback1.callback(), log.bound());
3142 EXPECT_EQ(OK, callback1.GetResult(rv));
3143
mmenke43758e62015-05-04 21:09:463144 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403145 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393146 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403147 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:393148 NetLog::PHASE_NONE);
3149 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403150 entries, pos,
[email protected]dbb83db2010-05-11 18:13:393151 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3152 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:323153
[email protected]1c773ea12009-04-28 19:58:423154 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243155 ASSERT_TRUE(response);
3156 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323157 EXPECT_TRUE(response->headers->IsKeepAlive());
3158 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423159 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043160 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323161
mmenked39192ee2015-12-09 00:57:233162 LoadTimingInfo load_timing_info;
3163 // CONNECT requests and responses are handled at the connect job level, so
3164 // the transaction does not yet have a connection.
3165 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3166
[email protected]49639fa2011-12-20 23:22:413167 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323168
mmenked39192ee2015-12-09 00:57:233169 rv =
3170 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3171 EXPECT_EQ(OK, callback2.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:323172
[email protected]2d2697f92009-02-18 21:00:323173 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233174 EXPECT_EQ(200, response->headers->response_code());
3175 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423176 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133177
mmenked39192ee2015-12-09 00:57:233178 // The password prompt info should not be set.
3179 EXPECT_FALSE(response->auth_challenge);
3180
3181 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3182 TestLoadTimingNotReusedWithPac(load_timing_info,
3183 CONNECT_TIMING_HAS_SSL_TIMES);
3184
3185 trans.reset();
[email protected]102e27c2011-02-23 01:01:313186 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323187}
3188
mmenkee71e15332015-10-07 16:39:543189// Test the case a proxy closes a socket while the challenge body is being
3190// drained.
3191TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
3192 HttpRequestInfo request;
3193 request.method = "GET";
3194 request.url = GURL("https://www.example.org/");
3195 // Ensure that proxy authentication is attempted even
3196 // when the no authentication data flag is set.
3197 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3198
3199 // Configure against proxy server "myproxy:70".
3200 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:423201 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543202
3203 scoped_ptr<HttpTransaction> trans(
3204 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3205
3206 // Since we have proxy, should try to establish tunnel.
3207 MockWrite data_writes1[] = {
3208 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173209 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543210 "Proxy-Connection: keep-alive\r\n\r\n"),
3211 };
3212
3213 // The proxy responds to the connect with a 407, using a persistent
3214 // connection.
3215 MockRead data_reads1[] = {
3216 // No credentials.
3217 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3218 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3219 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3220 // Server hands up in the middle of the body.
3221 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3222 };
3223
3224 MockWrite data_writes2[] = {
3225 // After calling trans->RestartWithAuth(), this is the request we should
3226 // be issuing -- the final header line contains the credentials.
3227 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173228 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543229 "Proxy-Connection: keep-alive\r\n"
3230 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3231
3232 MockWrite("GET / HTTP/1.1\r\n"
3233 "Host: www.example.org\r\n"
3234 "Connection: keep-alive\r\n\r\n"),
3235 };
3236
3237 MockRead data_reads2[] = {
3238 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3239
3240 MockRead("HTTP/1.1 200 OK\r\n"),
3241 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3242 MockRead("Content-Length: 5\r\n\r\n"),
3243 MockRead(SYNCHRONOUS, "hello"),
3244 };
3245
3246 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3247 data_writes1, arraysize(data_writes1));
3248 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3249 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3250 data_writes2, arraysize(data_writes2));
3251 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3252 SSLSocketDataProvider ssl(ASYNC, OK);
3253 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3254
3255 TestCompletionCallback callback;
3256
3257 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3258 EXPECT_EQ(OK, callback.GetResult(rv));
3259
3260 const HttpResponseInfo* response = trans->GetResponseInfo();
3261 ASSERT_TRUE(response);
3262 ASSERT_TRUE(response->headers);
3263 EXPECT_TRUE(response->headers->IsKeepAlive());
3264 EXPECT_EQ(407, response->headers->response_code());
3265 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3266
3267 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
3268 EXPECT_EQ(OK, callback.GetResult(rv));
3269
3270 response = trans->GetResponseInfo();
3271 ASSERT_TRUE(response);
3272 ASSERT_TRUE(response->headers);
3273 EXPECT_TRUE(response->headers->IsKeepAlive());
3274 EXPECT_EQ(200, response->headers->response_code());
3275 std::string body;
3276 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
3277 EXPECT_EQ("hello", body);
3278}
3279
[email protected]a8e9b162009-03-12 00:06:443280// Test that we don't read the response body when we fail to establish a tunnel,
3281// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:023282TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273283 HttpRequestInfo request;
3284 request.method = "GET";
bncce36dca22015-04-21 22:11:233285 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273286 request.load_flags = 0;
3287
[email protected]a8e9b162009-03-12 00:06:443288 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033289 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443290
mmenkee65e7af2015-10-13 17:16:423291 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443292
[email protected]262eec82013-03-19 21:01:363293 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503294 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:443295
[email protected]a8e9b162009-03-12 00:06:443296 // Since we have proxy, should try to establish tunnel.
3297 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173298 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3299 "Host: www.example.org:443\r\n"
3300 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443301 };
3302
3303 // The proxy responds to the connect with a 407.
3304 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243305 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3306 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3307 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233308 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243309 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443310 };
3311
[email protected]31a2bfe2010-02-09 08:03:393312 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3313 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073314 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443315
[email protected]49639fa2011-12-20 23:22:413316 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443317
[email protected]49639fa2011-12-20 23:22:413318 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423319 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:443320
3321 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423322 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:443323
[email protected]1c773ea12009-04-28 19:58:423324 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243325 ASSERT_TRUE(response);
3326 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443327 EXPECT_TRUE(response->headers->IsKeepAlive());
3328 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423329 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443330
3331 std::string response_data;
3332 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423333 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:183334
3335 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313336 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443337}
3338
ttuttle7933c112015-01-06 00:55:243339// Test that we don't pass extraneous headers from the proxy's response to the
3340// caller when the proxy responds to CONNECT with 407.
3341TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3342 HttpRequestInfo request;
3343 request.method = "GET";
bncce36dca22015-04-21 22:11:233344 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243345 request.load_flags = 0;
3346
3347 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033348 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243349
mmenkee65e7af2015-10-13 17:16:423350 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243351
3352 scoped_ptr<HttpTransaction> trans(
3353 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3354
3355 // Since we have proxy, should try to establish tunnel.
3356 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173357 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3358 "Host: www.example.org:443\r\n"
3359 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243360 };
3361
3362 // The proxy responds to the connect with a 407.
3363 MockRead data_reads[] = {
3364 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3365 MockRead("X-Foo: bar\r\n"),
3366 MockRead("Set-Cookie: foo=bar\r\n"),
3367 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3368 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233369 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243370 };
3371
3372 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3373 arraysize(data_writes));
3374 session_deps_.socket_factory->AddSocketDataProvider(&data);
3375
3376 TestCompletionCallback callback;
3377
3378 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3379 EXPECT_EQ(ERR_IO_PENDING, rv);
3380
3381 rv = callback.WaitForResult();
3382 EXPECT_EQ(OK, rv);
3383
3384 const HttpResponseInfo* response = trans->GetResponseInfo();
3385 ASSERT_TRUE(response);
3386 ASSERT_TRUE(response->headers);
3387 EXPECT_TRUE(response->headers->IsKeepAlive());
3388 EXPECT_EQ(407, response->headers->response_code());
3389 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3390 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3391 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3392
3393 std::string response_data;
3394 rv = ReadTransaction(trans.get(), &response_data);
3395 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3396
3397 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3398 session->CloseAllConnections();
3399}
3400
[email protected]8fdbcd22010-05-05 02:54:523401// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3402// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023403TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523404 HttpRequestInfo request;
3405 request.method = "GET";
bncce36dca22015-04-21 22:11:233406 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523407 request.load_flags = 0;
3408
[email protected]cb9bf6ca2011-01-28 13:15:273409 // We are using a DIRECT connection (i.e. no proxy) for this session.
mmenkee65e7af2015-10-13 17:16:423410 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273411 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413412 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273413
[email protected]8fdbcd22010-05-05 02:54:523414 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233415 MockWrite(
3416 "GET / HTTP/1.1\r\n"
3417 "Host: www.example.org\r\n"
3418 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523419 };
3420
3421 MockRead data_reads1[] = {
3422 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3423 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3424 // Large content-length -- won't matter, as connection will be reset.
3425 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063426 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523427 };
3428
3429 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3430 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073431 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523432
[email protected]49639fa2011-12-20 23:22:413433 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523434
[email protected]49639fa2011-12-20 23:22:413435 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523436 EXPECT_EQ(ERR_IO_PENDING, rv);
3437
3438 rv = callback.WaitForResult();
3439 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3440}
3441
[email protected]7a67a8152010-11-05 18:31:103442// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3443// through a non-authenticating proxy. The request should fail with
3444// ERR_UNEXPECTED_PROXY_AUTH.
3445// Note that it is impossible to detect if an HTTP server returns a 407 through
3446// a non-authenticating proxy - there is nothing to indicate whether the
3447// response came from the proxy or the server, so it is treated as if the proxy
3448// issued the challenge.
[email protected]23e482282013-06-14 16:08:023449TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233450 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273451 HttpRequestInfo request;
3452 request.method = "GET";
bncce36dca22015-04-21 22:11:233453 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273454
rdsmith82957ad2015-09-16 19:42:033455 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513456 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073457 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423458 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103459
[email protected]7a67a8152010-11-05 18:31:103460 // Since we have proxy, should try to establish tunnel.
3461 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173462 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3463 "Host: www.example.org:443\r\n"
3464 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103465
rsleevidb16bb02015-11-12 23:47:173466 MockWrite("GET / HTTP/1.1\r\n"
3467 "Host: www.example.org\r\n"
3468 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103469 };
3470
3471 MockRead data_reads1[] = {
3472 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3473
3474 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3475 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3476 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063477 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103478 };
3479
3480 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3481 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073482 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063483 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073484 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103485
[email protected]49639fa2011-12-20 23:22:413486 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103487
[email protected]262eec82013-03-19 21:01:363488 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503489 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103490
[email protected]49639fa2011-12-20 23:22:413491 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103492 EXPECT_EQ(ERR_IO_PENDING, rv);
3493
3494 rv = callback1.WaitForResult();
3495 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463496 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403497 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103498 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403499 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103500 NetLog::PHASE_NONE);
3501 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403502 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103503 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3504 NetLog::PHASE_NONE);
3505}
[email protected]2df19bb2010-08-25 20:13:463506
mmenke2a1781d2015-10-07 19:25:333507// Test a proxy auth scheme that allows default credentials and a proxy server
3508// that uses non-persistent connections.
3509TEST_P(HttpNetworkTransactionTest,
3510 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3511 HttpRequestInfo request;
3512 request.method = "GET";
3513 request.url = GURL("https://www.example.org/");
3514
3515 // Configure against proxy server "myproxy:70".
3516 session_deps_.proxy_service =
3517 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3518
3519 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3520 new HttpAuthHandlerMock::Factory());
3521 auth_handler_factory->set_do_init_from_challenge(true);
3522 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3523 mock_handler->set_allows_default_credentials(true);
3524 auth_handler_factory->AddMockHandler(mock_handler.release(),
3525 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483526 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333527
3528 // Add NetLog just so can verify load timing information gets a NetLog ID.
3529 NetLog net_log;
3530 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423531 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333532
3533 // Since we have proxy, should try to establish tunnel.
3534 MockWrite data_writes1[] = {
3535 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173536 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333537 "Proxy-Connection: keep-alive\r\n\r\n"),
3538 };
3539
3540 // The proxy responds to the connect with a 407, using a non-persistent
3541 // connection.
3542 MockRead data_reads1[] = {
3543 // No credentials.
3544 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3545 MockRead("Proxy-Authenticate: Mock\r\n"),
3546 MockRead("Proxy-Connection: close\r\n\r\n"),
3547 };
3548
3549 // Since the first connection couldn't be reused, need to establish another
3550 // once given credentials.
3551 MockWrite data_writes2[] = {
3552 // After calling trans->RestartWithAuth(), this is the request we should
3553 // be issuing -- the final header line contains the credentials.
3554 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173555 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333556 "Proxy-Connection: keep-alive\r\n"
3557 "Proxy-Authorization: auth_token\r\n\r\n"),
3558
3559 MockWrite("GET / HTTP/1.1\r\n"
3560 "Host: www.example.org\r\n"
3561 "Connection: keep-alive\r\n\r\n"),
3562 };
3563
3564 MockRead data_reads2[] = {
3565 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3566
3567 MockRead("HTTP/1.1 200 OK\r\n"),
3568 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3569 MockRead("Content-Length: 5\r\n\r\n"),
3570 MockRead(SYNCHRONOUS, "hello"),
3571 };
3572
3573 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3574 data_writes1, arraysize(data_writes1));
3575 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3576 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3577 data_writes2, arraysize(data_writes2));
3578 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3579 SSLSocketDataProvider ssl(ASYNC, OK);
3580 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3581
3582 scoped_ptr<HttpTransaction> trans(
3583 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3584
3585 TestCompletionCallback callback;
3586 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3587 EXPECT_EQ(OK, callback.GetResult(rv));
3588
3589 const HttpResponseInfo* response = trans->GetResponseInfo();
3590 ASSERT_TRUE(response);
3591 ASSERT_TRUE(response->headers);
3592 EXPECT_FALSE(response->headers->IsKeepAlive());
3593 EXPECT_EQ(407, response->headers->response_code());
3594 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3595 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3596 EXPECT_FALSE(response->auth_challenge.get());
3597
3598 LoadTimingInfo load_timing_info;
3599 // CONNECT requests and responses are handled at the connect job level, so
3600 // the transaction does not yet have a connection.
3601 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3602
3603 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3604 EXPECT_EQ(OK, callback.GetResult(rv));
3605 response = trans->GetResponseInfo();
3606 ASSERT_TRUE(response);
3607 ASSERT_TRUE(response->headers);
3608 EXPECT_TRUE(response->headers->IsKeepAlive());
3609 EXPECT_EQ(200, response->headers->response_code());
3610 EXPECT_EQ(5, response->headers->GetContentLength());
3611 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3612
3613 // The password prompt info should not be set.
3614 EXPECT_FALSE(response->auth_challenge);
3615
3616 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3617 TestLoadTimingNotReusedWithPac(load_timing_info,
3618 CONNECT_TIMING_HAS_SSL_TIMES);
3619
3620 trans.reset();
3621 session->CloseAllConnections();
3622}
3623
3624// Test a proxy auth scheme that allows default credentials and a proxy server
3625// that hangs up when credentials are initially sent.
3626TEST_P(HttpNetworkTransactionTest,
3627 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3628 HttpRequestInfo request;
3629 request.method = "GET";
3630 request.url = GURL("https://www.example.org/");
3631
3632 // Configure against proxy server "myproxy:70".
3633 session_deps_.proxy_service =
3634 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3635
3636 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3637 new HttpAuthHandlerMock::Factory());
3638 auth_handler_factory->set_do_init_from_challenge(true);
3639 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3640 mock_handler->set_allows_default_credentials(true);
3641 auth_handler_factory->AddMockHandler(mock_handler.release(),
3642 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483643 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333644
3645 // Add NetLog just so can verify load timing information gets a NetLog ID.
3646 NetLog net_log;
3647 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423648 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333649
3650 // Should try to establish tunnel.
3651 MockWrite data_writes1[] = {
3652 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173653 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333654 "Proxy-Connection: keep-alive\r\n\r\n"),
3655
3656 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173657 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333658 "Proxy-Connection: keep-alive\r\n"
3659 "Proxy-Authorization: auth_token\r\n\r\n"),
3660 };
3661
3662 // The proxy responds to the connect with a 407, using a non-persistent
3663 // connection.
3664 MockRead data_reads1[] = {
3665 // No credentials.
3666 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3667 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3668 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3669 };
3670
3671 // Since the first connection was closed, need to establish another once given
3672 // credentials.
3673 MockWrite data_writes2[] = {
3674 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173675 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333676 "Proxy-Connection: keep-alive\r\n"
3677 "Proxy-Authorization: auth_token\r\n\r\n"),
3678
3679 MockWrite("GET / HTTP/1.1\r\n"
3680 "Host: www.example.org\r\n"
3681 "Connection: keep-alive\r\n\r\n"),
3682 };
3683
3684 MockRead data_reads2[] = {
3685 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3686
3687 MockRead("HTTP/1.1 200 OK\r\n"),
3688 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3689 MockRead("Content-Length: 5\r\n\r\n"),
3690 MockRead(SYNCHRONOUS, "hello"),
3691 };
3692
3693 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3694 data_writes1, arraysize(data_writes1));
3695 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3696 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3697 data_writes2, arraysize(data_writes2));
3698 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3699 SSLSocketDataProvider ssl(ASYNC, OK);
3700 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3701
3702 scoped_ptr<HttpTransaction> trans(
3703 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3704
3705 TestCompletionCallback callback;
3706 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3707 EXPECT_EQ(OK, callback.GetResult(rv));
3708
3709 const HttpResponseInfo* response = trans->GetResponseInfo();
3710 ASSERT_TRUE(response);
3711 ASSERT_TRUE(response->headers);
3712 EXPECT_TRUE(response->headers->IsKeepAlive());
3713 EXPECT_EQ(407, response->headers->response_code());
3714 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3715 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3716 EXPECT_FALSE(response->auth_challenge);
3717
3718 LoadTimingInfo load_timing_info;
3719 // CONNECT requests and responses are handled at the connect job level, so
3720 // the transaction does not yet have a connection.
3721 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3722
3723 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3724 EXPECT_EQ(OK, callback.GetResult(rv));
3725
3726 response = trans->GetResponseInfo();
3727 ASSERT_TRUE(response);
3728 ASSERT_TRUE(response->headers);
3729 EXPECT_TRUE(response->headers->IsKeepAlive());
3730 EXPECT_EQ(200, response->headers->response_code());
3731 EXPECT_EQ(5, response->headers->GetContentLength());
3732 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3733
3734 // The password prompt info should not be set.
3735 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3736
3737 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3738 TestLoadTimingNotReusedWithPac(load_timing_info,
3739 CONNECT_TIMING_HAS_SSL_TIMES);
3740
3741 trans.reset();
3742 session->CloseAllConnections();
3743}
3744
3745// Test a proxy auth scheme that allows default credentials and a proxy server
3746// that hangs up when credentials are initially sent, and hangs up again when
3747// they are retried.
3748TEST_P(HttpNetworkTransactionTest,
3749 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
3750 HttpRequestInfo request;
3751 request.method = "GET";
3752 request.url = GURL("https://www.example.org/");
3753
3754 // Configure against proxy server "myproxy:70".
3755 session_deps_.proxy_service =
3756 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3757
3758 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3759 new HttpAuthHandlerMock::Factory());
3760 auth_handler_factory->set_do_init_from_challenge(true);
3761 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3762 mock_handler->set_allows_default_credentials(true);
3763 auth_handler_factory->AddMockHandler(mock_handler.release(),
3764 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483765 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333766
3767 // Add NetLog just so can verify load timing information gets a NetLog ID.
3768 NetLog net_log;
3769 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423770 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333771
3772 // Should try to establish tunnel.
3773 MockWrite data_writes1[] = {
3774 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173775 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333776 "Proxy-Connection: keep-alive\r\n\r\n"),
3777
3778 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173779 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333780 "Proxy-Connection: keep-alive\r\n"
3781 "Proxy-Authorization: auth_token\r\n\r\n"),
3782 };
3783
3784 // The proxy responds to the connect with a 407, and then hangs up after the
3785 // second request is sent.
3786 MockRead data_reads1[] = {
3787 // No credentials.
3788 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3789 MockRead("Content-Length: 0\r\n"),
3790 MockRead("Proxy-Connection: keep-alive\r\n"),
3791 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3792 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3793 };
3794
3795 // HttpNetworkTransaction sees a reused connection that was closed with
3796 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
3797 // request.
3798 MockWrite data_writes2[] = {
3799 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173800 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333801 "Proxy-Connection: keep-alive\r\n\r\n"),
3802 };
3803
3804 // The proxy, having had more than enough of us, just hangs up.
3805 MockRead data_reads2[] = {
3806 // No credentials.
3807 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3808 };
3809
3810 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3811 data_writes1, arraysize(data_writes1));
3812 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3813 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3814 data_writes2, arraysize(data_writes2));
3815 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3816
3817 scoped_ptr<HttpTransaction> trans(
3818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3819
3820 TestCompletionCallback callback;
3821 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3822 EXPECT_EQ(OK, callback.GetResult(rv));
3823
3824 const HttpResponseInfo* response = trans->GetResponseInfo();
3825 ASSERT_TRUE(response);
3826 ASSERT_TRUE(response->headers);
3827 EXPECT_TRUE(response->headers->IsKeepAlive());
3828 EXPECT_EQ(407, response->headers->response_code());
3829 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3830 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3831 EXPECT_FALSE(response->auth_challenge);
3832
3833 LoadTimingInfo load_timing_info;
3834 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3835
3836 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3837 EXPECT_EQ(ERR_EMPTY_RESPONSE, callback.GetResult(rv));
3838
3839 trans.reset();
3840 session->CloseAllConnections();
3841}
3842
3843// Test a proxy auth scheme that allows default credentials and a proxy server
3844// that hangs up when credentials are initially sent, and sends a challenge
3845// again they are retried.
3846TEST_P(HttpNetworkTransactionTest,
3847 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
3848 HttpRequestInfo request;
3849 request.method = "GET";
3850 request.url = GURL("https://www.example.org/");
3851
3852 // Configure against proxy server "myproxy:70".
3853 session_deps_.proxy_service =
3854 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3855
3856 scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
3857 new HttpAuthHandlerMock::Factory());
3858 auth_handler_factory->set_do_init_from_challenge(true);
3859 scoped_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
3860 mock_handler->set_allows_default_credentials(true);
3861 auth_handler_factory->AddMockHandler(mock_handler.release(),
3862 HttpAuth::AUTH_PROXY);
3863 // Add another handler for the second challenge. It supports default
3864 // credentials, but they shouldn't be used, since they were already tried.
3865 mock_handler.reset(new HttpAuthHandlerMock());
3866 mock_handler->set_allows_default_credentials(true);
3867 auth_handler_factory->AddMockHandler(mock_handler.release(),
3868 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483869 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333870
3871 // Add NetLog just so can verify load timing information gets a NetLog ID.
3872 NetLog net_log;
3873 session_deps_.net_log = &net_log;
mmenkee65e7af2015-10-13 17:16:423874 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333875
3876 // Should try to establish tunnel.
3877 MockWrite data_writes1[] = {
3878 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173879 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333880 "Proxy-Connection: keep-alive\r\n\r\n"),
3881 };
3882
3883 // The proxy responds to the connect with a 407, using a non-persistent
3884 // connection.
3885 MockRead data_reads1[] = {
3886 // No credentials.
3887 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3888 MockRead("Proxy-Authenticate: Mock\r\n"),
3889 MockRead("Proxy-Connection: close\r\n\r\n"),
3890 };
3891
3892 // Since the first connection was closed, need to establish another once given
3893 // credentials.
3894 MockWrite data_writes2[] = {
3895 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173896 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333897 "Proxy-Connection: keep-alive\r\n"
3898 "Proxy-Authorization: auth_token\r\n\r\n"),
3899 };
3900
3901 MockRead data_reads2[] = {
3902 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3903 MockRead("Proxy-Authenticate: Mock\r\n"),
3904 MockRead("Proxy-Connection: close\r\n\r\n"),
3905 };
3906
3907 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3908 data_writes1, arraysize(data_writes1));
3909 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3910 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3911 data_writes2, arraysize(data_writes2));
3912 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3913 SSLSocketDataProvider ssl(ASYNC, OK);
3914 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3915
3916 scoped_ptr<HttpTransaction> trans(
3917 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3918
3919 TestCompletionCallback callback;
3920 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3921 EXPECT_EQ(OK, callback.GetResult(rv));
3922
3923 const HttpResponseInfo* response = trans->GetResponseInfo();
3924 ASSERT_TRUE(response);
3925 ASSERT_TRUE(response->headers);
3926 EXPECT_EQ(407, response->headers->response_code());
3927 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3928 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
3929 EXPECT_FALSE(response->auth_challenge);
3930
3931 LoadTimingInfo load_timing_info;
3932 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3933
3934 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3935 EXPECT_EQ(OK, callback.GetResult(rv));
3936 response = trans->GetResponseInfo();
3937 ASSERT_TRUE(response);
3938 ASSERT_TRUE(response->headers);
3939 EXPECT_EQ(407, response->headers->response_code());
3940 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
3941 EXPECT_TRUE(response->auth_challenge);
3942
3943 trans.reset();
3944 session->CloseAllConnections();
3945}
3946
[email protected]029c83b62013-01-24 05:28:203947// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023948TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203949 HttpRequestInfo request1;
3950 request1.method = "GET";
bncce36dca22015-04-21 22:11:233951 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203952
3953 HttpRequestInfo request2;
3954 request2.method = "GET";
bncce36dca22015-04-21 22:11:233955 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203956
3957 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033958 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513959 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073960 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:423961 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203962
3963 // Since we have proxy, should try to establish tunnel.
3964 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173965 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3966 "Host: www.example.org:443\r\n"
3967 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203968
rsleevidb16bb02015-11-12 23:47:173969 MockWrite("GET /1 HTTP/1.1\r\n"
3970 "Host: www.example.org\r\n"
3971 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203972
rsleevidb16bb02015-11-12 23:47:173973 MockWrite("GET /2 HTTP/1.1\r\n"
3974 "Host: www.example.org\r\n"
3975 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203976 };
3977
3978 // The proxy responds to the connect with a 407, using a persistent
3979 // connection.
3980 MockRead data_reads1[] = {
3981 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3982
3983 MockRead("HTTP/1.1 200 OK\r\n"),
3984 MockRead("Content-Length: 1\r\n\r\n"),
3985 MockRead(SYNCHRONOUS, "1"),
3986
3987 MockRead("HTTP/1.1 200 OK\r\n"),
3988 MockRead("Content-Length: 2\r\n\r\n"),
3989 MockRead(SYNCHRONOUS, "22"),
3990 };
3991
3992 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3993 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073994 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203995 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073996 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203997
3998 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363999 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:504000 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204001
4002 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
4003 EXPECT_EQ(ERR_IO_PENDING, rv);
4004
4005 rv = callback1.WaitForResult();
4006 EXPECT_EQ(OK, rv);
4007
4008 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
4009 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:504010 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:204011 EXPECT_EQ(1, response1->headers->GetContentLength());
4012
4013 LoadTimingInfo load_timing_info1;
4014 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4015 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4016
4017 trans1.reset();
4018
4019 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:364020 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504021 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204022
4023 rv = trans2->Start(&request2, callback2.callback(), log.bound());
4024 EXPECT_EQ(ERR_IO_PENDING, rv);
4025
4026 rv = callback2.WaitForResult();
4027 EXPECT_EQ(OK, rv);
4028
4029 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
4030 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:504031 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:204032 EXPECT_EQ(2, response2->headers->GetContentLength());
4033
4034 LoadTimingInfo load_timing_info2;
4035 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4036 TestLoadTimingReused(load_timing_info2);
4037
4038 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4039
4040 trans2.reset();
4041 session->CloseAllConnections();
4042}
4043
4044// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:024045TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204046 HttpRequestInfo request1;
4047 request1.method = "GET";
bncce36dca22015-04-21 22:11:234048 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204049
4050 HttpRequestInfo request2;
4051 request2.method = "GET";
bncce36dca22015-04-21 22:11:234052 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204053
4054 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034055 session_deps_.proxy_service =
4056 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514057 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074058 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424059 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204060
4061 // Since we have proxy, should try to establish tunnel.
4062 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174063 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4064 "Host: www.example.org:443\r\n"
4065 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204066
rsleevidb16bb02015-11-12 23:47:174067 MockWrite("GET /1 HTTP/1.1\r\n"
4068 "Host: www.example.org\r\n"
4069 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204070
rsleevidb16bb02015-11-12 23:47:174071 MockWrite("GET /2 HTTP/1.1\r\n"
4072 "Host: www.example.org\r\n"
4073 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204074 };
4075
4076 // The proxy responds to the connect with a 407, using a persistent
4077 // connection.
4078 MockRead data_reads1[] = {
4079 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4080
4081 MockRead("HTTP/1.1 200 OK\r\n"),
4082 MockRead("Content-Length: 1\r\n\r\n"),
4083 MockRead(SYNCHRONOUS, "1"),
4084
4085 MockRead("HTTP/1.1 200 OK\r\n"),
4086 MockRead("Content-Length: 2\r\n\r\n"),
4087 MockRead(SYNCHRONOUS, "22"),
4088 };
4089
4090 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4091 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074092 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204093 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074094 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204095
4096 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:364097 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:504098 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204099
4100 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
4101 EXPECT_EQ(ERR_IO_PENDING, rv);
4102
4103 rv = callback1.WaitForResult();
4104 EXPECT_EQ(OK, rv);
4105
4106 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
4107 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:504108 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:204109 EXPECT_EQ(1, response1->headers->GetContentLength());
4110
4111 LoadTimingInfo load_timing_info1;
4112 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4113 TestLoadTimingNotReusedWithPac(load_timing_info1,
4114 CONNECT_TIMING_HAS_SSL_TIMES);
4115
4116 trans1.reset();
4117
4118 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:364119 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204121
4122 rv = trans2->Start(&request2, callback2.callback(), log.bound());
4123 EXPECT_EQ(ERR_IO_PENDING, rv);
4124
4125 rv = callback2.WaitForResult();
4126 EXPECT_EQ(OK, rv);
4127
4128 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
4129 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:504130 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:204131 EXPECT_EQ(2, response2->headers->GetContentLength());
4132
4133 LoadTimingInfo load_timing_info2;
4134 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4135 TestLoadTimingReusedWithPac(load_timing_info2);
4136
4137 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4138
4139 trans2.reset();
4140 session->CloseAllConnections();
4141}
4142
[email protected]2df19bb2010-08-25 20:13:464143// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024144TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274145 HttpRequestInfo request;
4146 request.method = "GET";
bncce36dca22015-04-21 22:11:234147 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274148
[email protected]2df19bb2010-08-25 20:13:464149 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034150 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514151 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074152 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424153 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464154
[email protected]2df19bb2010-08-25 20:13:464155 // Since we have proxy, should use full url
4156 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234157 MockWrite(
4158 "GET http://www.example.org/ HTTP/1.1\r\n"
4159 "Host: www.example.org\r\n"
4160 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464161 };
4162
4163 MockRead data_reads1[] = {
4164 MockRead("HTTP/1.1 200 OK\r\n"),
4165 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4166 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064167 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464168 };
4169
4170 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4171 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074172 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064173 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074174 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464175
[email protected]49639fa2011-12-20 23:22:414176 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464177
[email protected]262eec82013-03-19 21:01:364178 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504179 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504180
[email protected]49639fa2011-12-20 23:22:414181 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464182 EXPECT_EQ(ERR_IO_PENDING, rv);
4183
4184 rv = callback1.WaitForResult();
4185 EXPECT_EQ(OK, rv);
4186
[email protected]58e32bb2013-01-21 18:23:254187 LoadTimingInfo load_timing_info;
4188 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4189 TestLoadTimingNotReused(load_timing_info,
4190 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4191
[email protected]2df19bb2010-08-25 20:13:464192 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504193 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464194
4195 EXPECT_TRUE(response->headers->IsKeepAlive());
4196 EXPECT_EQ(200, response->headers->response_code());
4197 EXPECT_EQ(100, response->headers->GetContentLength());
4198 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4199
4200 // The password prompt info should not be set.
4201 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4202}
4203
[email protected]7642b5ae2010-09-01 20:55:174204// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024205TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274206 HttpRequestInfo request;
4207 request.method = "GET";
bncce36dca22015-04-21 22:11:234208 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274209 request.load_flags = 0;
4210
[email protected]7642b5ae2010-09-01 20:55:174211 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034212 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514213 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074214 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424215 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174216
bncce36dca22015-04-21 22:11:234217 // fetch http://www.example.org/ via SPDY
bncb03b1092016-04-06 11:19:554218 scoped_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:494219 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134220 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174221
bncb03b1092016-04-06 11:19:554222 scoped_ptr<SpdySerializedFrame> resp(
4223 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
4224 scoped_ptr<SpdySerializedFrame> data(
4225 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174226 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134227 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174228 };
4229
rch8e6c6c42015-05-01 14:05:134230 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4231 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074232 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174233
[email protected]8ddf8322012-02-23 18:08:064234 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384235 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074236 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174237
[email protected]49639fa2011-12-20 23:22:414238 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174239
[email protected]262eec82013-03-19 21:01:364240 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504241 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504242
[email protected]49639fa2011-12-20 23:22:414243 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:174244 EXPECT_EQ(ERR_IO_PENDING, rv);
4245
4246 rv = callback1.WaitForResult();
4247 EXPECT_EQ(OK, rv);
4248
[email protected]58e32bb2013-01-21 18:23:254249 LoadTimingInfo load_timing_info;
4250 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4251 TestLoadTimingNotReused(load_timing_info,
4252 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4253
[email protected]7642b5ae2010-09-01 20:55:174254 const HttpResponseInfo* response = trans->GetResponseInfo();
4255 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504256 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:024257 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174258
4259 std::string response_data;
4260 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234261 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174262}
4263
[email protected]1c173852014-06-19 12:51:504264// Verifies that a session which races and wins against the owning transaction
4265// (completing prior to host resolution), doesn't fail the transaction.
4266// Regression test for crbug.com/334413.
4267TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
4268 HttpRequestInfo request;
4269 request.method = "GET";
bncce36dca22015-04-21 22:11:234270 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504271 request.load_flags = 0;
4272
4273 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034274 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514275 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504276 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424277 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504278
bncce36dca22015-04-21 22:11:234279 // Fetch http://www.example.org/ through the SPDY proxy.
bncb03b1092016-04-06 11:19:554280 scoped_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:494281 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134282 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:504283
bncb03b1092016-04-06 11:19:554284 scoped_ptr<SpdySerializedFrame> resp(
4285 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4286 scoped_ptr<SpdySerializedFrame> data(
4287 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]1c173852014-06-19 12:51:504288 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134289 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504290 };
4291
rch8e6c6c42015-05-01 14:05:134292 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4293 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504294 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4295
4296 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384297 ssl.SetNextProto(GetProtocol());
[email protected]1c173852014-06-19 12:51:504298 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4299
4300 TestCompletionCallback callback1;
4301
4302 scoped_ptr<HttpTransaction> trans(
4303 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4304
4305 // Stall the hostname resolution begun by the transaction.
4306 session_deps_.host_resolver->set_synchronous_mode(false);
4307 session_deps_.host_resolver->set_ondemand_mode(true);
4308
4309 int rv = trans->Start(&request, callback1.callback(), log.bound());
4310 EXPECT_EQ(ERR_IO_PENDING, rv);
4311
4312 // Race a session to the proxy, which completes first.
4313 session_deps_.host_resolver->set_ondemand_mode(false);
4314 SpdySessionKey key(
4315 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4316 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424317 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504318
4319 // Unstall the resolution begun by the transaction.
4320 session_deps_.host_resolver->set_ondemand_mode(true);
4321 session_deps_.host_resolver->ResolveAllPending();
4322
4323 EXPECT_FALSE(callback1.have_result());
4324 rv = callback1.WaitForResult();
4325 EXPECT_EQ(OK, rv);
4326
4327 const HttpResponseInfo* response = trans->GetResponseInfo();
4328 ASSERT_TRUE(response != NULL);
4329 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:024330 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504331
4332 std::string response_data;
4333 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4334 EXPECT_EQ(kUploadData, response_data);
4335}
4336
[email protected]dc7bd1c52010-11-12 00:01:134337// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024338TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274339 HttpRequestInfo request;
4340 request.method = "GET";
bncce36dca22015-04-21 22:11:234341 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274342 request.load_flags = 0;
4343
[email protected]79cb5c12011-09-12 13:12:044344 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034345 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514346 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074347 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424348 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134349
[email protected]dc7bd1c52010-11-12 00:01:134350 // The first request will be a bare GET, the second request will be a
4351 // GET with a Proxy-Authorization header.
bncb03b1092016-04-06 11:19:554352 scoped_ptr<SpdySerializedFrame> req_get(
bnc38dcd392016-02-09 23:19:494353 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384354 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134355 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464356 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134357 };
bncb03b1092016-04-06 11:19:554358 scoped_ptr<SpdySerializedFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:464359 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
bncb03b1092016-04-06 11:19:554360 arraysize(kExtraAuthorizationHeaders) / 2, 3,
4361 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134362 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134363 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134364 };
4365
4366 // The first response is a 407 proxy authentication challenge, and the second
4367 // response will be a 200 response since the second request includes a valid
4368 // Authorization header.
4369 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464370 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134371 };
bncb03b1092016-04-06 11:19:554372 scoped_ptr<SpdySerializedFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:024373 spdy_util_.ConstructSpdySynReplyError(
bncb03b1092016-04-06 11:19:554374 "407 Proxy Authentication Required", kExtraAuthenticationHeaders,
4375 arraysize(kExtraAuthenticationHeaders) / 2, 1));
4376 scoped_ptr<SpdySerializedFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:024377 spdy_util_.ConstructSpdyBodyFrame(1, true));
bncb03b1092016-04-06 11:19:554378 scoped_ptr<SpdySerializedFrame> resp_data(
[email protected]23e482282013-06-14 16:08:024379 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
bncb03b1092016-04-06 11:19:554380 scoped_ptr<SpdySerializedFrame> body_data(
4381 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134382 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134383 CreateMockRead(*resp_authentication, 1),
4384 CreateMockRead(*body_authentication, 2),
4385 CreateMockRead(*resp_data, 4),
4386 CreateMockRead(*body_data, 5),
4387 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134388 };
4389
rch8e6c6c42015-05-01 14:05:134390 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4391 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074392 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134393
[email protected]8ddf8322012-02-23 18:08:064394 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384395 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074396 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134397
[email protected]49639fa2011-12-20 23:22:414398 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134399
[email protected]262eec82013-03-19 21:01:364400 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504401 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:134402
[email protected]49639fa2011-12-20 23:22:414403 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:134404 EXPECT_EQ(ERR_IO_PENDING, rv);
4405
4406 rv = callback1.WaitForResult();
4407 EXPECT_EQ(OK, rv);
4408
4409 const HttpResponseInfo* const response = trans->GetResponseInfo();
4410
4411 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504412 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:134413 EXPECT_EQ(407, response->headers->response_code());
4414 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:044415 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134416
[email protected]49639fa2011-12-20 23:22:414417 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134418
[email protected]49639fa2011-12-20 23:22:414419 rv = trans->RestartWithAuth(
4420 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:134421 EXPECT_EQ(ERR_IO_PENDING, rv);
4422
4423 rv = callback2.WaitForResult();
4424 EXPECT_EQ(OK, rv);
4425
4426 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
4427
4428 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:504429 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:134430 EXPECT_EQ(200, response_restart->headers->response_code());
4431 // The password prompt info should not be set.
4432 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
4433}
4434
[email protected]d9da5fe2010-10-13 22:37:164435// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:024436TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274437 HttpRequestInfo request;
4438 request.method = "GET";
bncce36dca22015-04-21 22:11:234439 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274440 request.load_flags = 0;
4441
[email protected]d9da5fe2010-10-13 22:37:164442 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034443 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514444 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074445 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424446 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164447
[email protected]262eec82013-03-19 21:01:364448 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504449 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164450
bncce36dca22015-04-21 22:11:234451 // CONNECT to www.example.org:443 via SPDY
bncb03b1092016-04-06 11:19:554452 scoped_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234453 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4454 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164455
bncce36dca22015-04-21 22:11:234456 const char get[] =
4457 "GET / HTTP/1.1\r\n"
4458 "Host: www.example.org\r\n"
4459 "Connection: keep-alive\r\n\r\n";
bncb03b1092016-04-06 11:19:554460 scoped_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024461 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
bncb03b1092016-04-06 11:19:554462 scoped_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:024463 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164464 const char resp[] = "HTTP/1.1 200 OK\r\n"
4465 "Content-Length: 10\r\n\r\n";
bncb03b1092016-04-06 11:19:554466 scoped_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024467 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
bncb03b1092016-04-06 11:19:554468 scoped_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024469 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
bncb03b1092016-04-06 11:19:554470 scoped_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204471 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:044472
4473 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134474 CreateMockWrite(*connect, 0),
4475 CreateMockWrite(*wrapped_get, 2),
4476 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044477 };
4478
[email protected]d9da5fe2010-10-13 22:37:164479 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134480 CreateMockRead(*conn_resp, 1, ASYNC),
4481 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
4482 CreateMockRead(*wrapped_body, 4, ASYNC),
4483 CreateMockRead(*wrapped_body, 5, ASYNC),
4484 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164485 };
4486
rch8e6c6c42015-05-01 14:05:134487 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4488 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074489 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164490
[email protected]8ddf8322012-02-23 18:08:064491 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384492 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074493 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064494 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074495 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164496
[email protected]49639fa2011-12-20 23:22:414497 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164498
[email protected]49639fa2011-12-20 23:22:414499 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164500 EXPECT_EQ(ERR_IO_PENDING, rv);
4501
4502 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:134503 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:164504
[email protected]58e32bb2013-01-21 18:23:254505 LoadTimingInfo load_timing_info;
4506 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4507 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4508
[email protected]d9da5fe2010-10-13 22:37:164509 const HttpResponseInfo* response = trans->GetResponseInfo();
4510 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504511 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:164512 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4513
4514 std::string response_data;
4515 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4516 EXPECT_EQ("1234567890", response_data);
4517}
4518
4519// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:024520TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
rdsmithebb50aa2015-11-12 03:44:384521 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
4522
[email protected]cb9bf6ca2011-01-28 13:15:274523 HttpRequestInfo request;
4524 request.method = "GET";
bncce36dca22015-04-21 22:11:234525 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274526 request.load_flags = 0;
4527
[email protected]d9da5fe2010-10-13 22:37:164528 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034529 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514530 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074531 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424532 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164533
[email protected]262eec82013-03-19 21:01:364534 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504535 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164536
bncce36dca22015-04-21 22:11:234537 // CONNECT to www.example.org:443 via SPDY
bncb03b1092016-04-06 11:19:554538 scoped_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234539 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4540 // fetch https://www.example.org/ via SPDY
4541 const char kMyUrl[] = "https://www.example.org/";
bncb03b1092016-04-06 11:19:554542 scoped_ptr<SpdySerializedFrame> get(
bnc38dcd392016-02-09 23:19:494543 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
bncb03b1092016-04-06 11:19:554544 scoped_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024545 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
bncb03b1092016-04-06 11:19:554546 scoped_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:024547 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
bncb03b1092016-04-06 11:19:554548 scoped_ptr<SpdySerializedFrame> get_resp(
rdsmithebb50aa2015-11-12 03:44:384549 spdy_util_wrapped.ConstructSpdyGetSynReply(NULL, 0, 1));
bncb03b1092016-04-06 11:19:554550 scoped_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024551 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
bncb03b1092016-04-06 11:19:554552 scoped_ptr<SpdySerializedFrame> body(
4553 spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
4554 scoped_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024555 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
bncb03b1092016-04-06 11:19:554556 scoped_ptr<SpdySerializedFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:204557 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
bncb03b1092016-04-06 11:19:554558 scoped_ptr<SpdySerializedFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:204559 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:044560
4561 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:094562 CreateMockWrite(*connect, 0),
4563 CreateMockWrite(*wrapped_get, 2),
4564 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:044565 CreateMockWrite(*window_update_body, 7),
4566 };
4567
[email protected]d9da5fe2010-10-13 22:37:164568 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:094569 CreateMockRead(*conn_resp, 1, ASYNC),
4570 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:134571 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:094572 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134573 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164574 };
4575
rch32320842015-05-16 15:57:094576 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4577 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074578 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164579
[email protected]8ddf8322012-02-23 18:08:064580 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384581 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074582 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064583 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384584 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074585 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164586
[email protected]49639fa2011-12-20 23:22:414587 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164588
[email protected]49639fa2011-12-20 23:22:414589 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164590 EXPECT_EQ(ERR_IO_PENDING, rv);
4591
rch32320842015-05-16 15:57:094592 // Allow the SpdyProxyClientSocket's write callback to complete.
4593 base::MessageLoop::current()->RunUntilIdle();
4594 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:594595 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:164596 rv = callback1.WaitForResult();
4597 EXPECT_EQ(OK, rv);
4598
[email protected]58e32bb2013-01-21 18:23:254599 LoadTimingInfo load_timing_info;
4600 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4601 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4602
[email protected]d9da5fe2010-10-13 22:37:164603 const HttpResponseInfo* response = trans->GetResponseInfo();
4604 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504605 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:024606 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:164607
4608 std::string response_data;
4609 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234610 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:164611}
4612
4613// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024614TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:274615 HttpRequestInfo request;
4616 request.method = "GET";
bncce36dca22015-04-21 22:11:234617 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274618 request.load_flags = 0;
4619
[email protected]d9da5fe2010-10-13 22:37:164620 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034621 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514622 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074623 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424624 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164625
[email protected]262eec82013-03-19 21:01:364626 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504627 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164628
bncce36dca22015-04-21 22:11:234629 // CONNECT to www.example.org:443 via SPDY
bncb03b1092016-04-06 11:19:554630 scoped_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234631 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncb03b1092016-04-06 11:19:554632 scoped_ptr<SpdySerializedFrame> get(
[email protected]c10b20852013-05-15 21:29:204633 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:164634
4635 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134636 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:164637 };
4638
bncb03b1092016-04-06 11:19:554639 scoped_ptr<SpdySerializedFrame> resp(
4640 spdy_util_.ConstructSpdySynReplyError(1));
4641 scoped_ptr<SpdySerializedFrame> data(
4642 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:164643 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134644 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:164645 };
4646
rch8e6c6c42015-05-01 14:05:134647 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4648 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074649 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164650
[email protected]8ddf8322012-02-23 18:08:064651 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384652 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074653 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064654 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384655 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074656 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164657
[email protected]49639fa2011-12-20 23:22:414658 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164659
[email protected]49639fa2011-12-20 23:22:414660 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164661 EXPECT_EQ(ERR_IO_PENDING, rv);
4662
4663 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:174664 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:164665
[email protected]4eddbc732012-08-09 05:40:174666 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:164667}
4668
[email protected]f6c63db52013-02-02 00:35:224669// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4670// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024671TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224672 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
4673 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034674 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514675 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074676 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424677 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504678 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224679
4680 HttpRequestInfo request1;
4681 request1.method = "GET";
bncce36dca22015-04-21 22:11:234682 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224683 request1.load_flags = 0;
4684
4685 HttpRequestInfo request2;
4686 request2.method = "GET";
bncce36dca22015-04-21 22:11:234687 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224688 request2.load_flags = 0;
4689
bncce36dca22015-04-21 22:11:234690 // CONNECT to www.example.org:443 via SPDY.
bncb03b1092016-04-06 11:19:554691 scoped_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234692 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncb03b1092016-04-06 11:19:554693 scoped_ptr<SpdySerializedFrame> conn_resp1(
[email protected]23e482282013-06-14 16:08:024694 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224695
bncce36dca22015-04-21 22:11:234696 // Fetch https://www.example.org/ via HTTP.
4697 const char get1[] =
4698 "GET / HTTP/1.1\r\n"
4699 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224700 "Connection: keep-alive\r\n\r\n";
bncb03b1092016-04-06 11:19:554701 scoped_ptr<SpdySerializedFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024702 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224703 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4704 "Content-Length: 1\r\n\r\n";
bncb03b1092016-04-06 11:19:554705 scoped_ptr<SpdySerializedFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024706 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
bncb03b1092016-04-06 11:19:554707 scoped_ptr<SpdySerializedFrame> wrapped_body1(
[email protected]23e482282013-06-14 16:08:024708 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
bncb03b1092016-04-06 11:19:554709 scoped_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204710 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224711
bncce36dca22015-04-21 22:11:234712 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:294713 SpdyHeaderBlock connect2_block;
bnc7ecc1122015-09-28 13:22:494714 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]745aa9c2014-06-27 02:21:294715 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
rdsmithebb50aa2015-11-12 03:44:384716 if (GetProtocol() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:324717 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
4718 } else {
bnc6b996d532015-07-29 10:51:324719 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
bnc7ecc1122015-09-28 13:22:494720 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
bnc6b996d532015-07-29 10:51:324721 }
bncb03b1092016-04-06 11:19:554722 scoped_ptr<SpdySerializedFrame> connect2(
bnc38dcd392016-02-09 23:19:494723 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false));
[email protected]601e03f12014-04-06 16:26:394724
bncb03b1092016-04-06 11:19:554725 scoped_ptr<SpdySerializedFrame> conn_resp2(
[email protected]23e482282013-06-14 16:08:024726 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:224727
bncce36dca22015-04-21 22:11:234728 // Fetch https://mail.example.org/ via HTTP.
4729 const char get2[] =
4730 "GET / HTTP/1.1\r\n"
4731 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224732 "Connection: keep-alive\r\n\r\n";
bncb03b1092016-04-06 11:19:554733 scoped_ptr<SpdySerializedFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024734 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224735 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4736 "Content-Length: 2\r\n\r\n";
bncb03b1092016-04-06 11:19:554737 scoped_ptr<SpdySerializedFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024738 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
bncb03b1092016-04-06 11:19:554739 scoped_ptr<SpdySerializedFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024740 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224741
4742 MockWrite spdy_writes[] = {
4743 CreateMockWrite(*connect1, 0),
4744 CreateMockWrite(*wrapped_get1, 2),
4745 CreateMockWrite(*connect2, 5),
4746 CreateMockWrite(*wrapped_get2, 7),
4747 };
4748
4749 MockRead spdy_reads[] = {
4750 CreateMockRead(*conn_resp1, 1, ASYNC),
4751 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4752 CreateMockRead(*wrapped_body1, 4, ASYNC),
4753 CreateMockRead(*conn_resp2, 6, ASYNC),
4754 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
4755 CreateMockRead(*wrapped_body2, 9, ASYNC),
4756 MockRead(ASYNC, 0, 10),
4757 };
4758
mmenke11eb5152015-06-09 14:50:504759 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4760 arraysize(spdy_writes));
4761 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224762
4763 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384764 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:504765 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224766 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504767 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224768 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504769 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:224770
4771 TestCompletionCallback callback;
4772
[email protected]262eec82013-03-19 21:01:364773 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504774 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224775 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504776 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224777
4778 LoadTimingInfo load_timing_info;
4779 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4780 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4781
4782 const HttpResponseInfo* response = trans->GetResponseInfo();
4783 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504784 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224785 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4786
4787 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294788 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504789 rv = trans->Read(buf.get(), 256, callback.callback());
4790 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224791
[email protected]262eec82013-03-19 21:01:364792 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504793 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224794 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504795 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224796
4797 LoadTimingInfo load_timing_info2;
4798 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4799 // Even though the SPDY connection is reused, a new tunnelled connection has
4800 // to be created, so the socket's load timing looks like a fresh connection.
4801 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
4802
4803 // The requests should have different IDs, since they each are using their own
4804 // separate stream.
4805 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4806
mmenke11eb5152015-06-09 14:50:504807 rv = trans2->Read(buf.get(), 256, callback.callback());
4808 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224809}
4810
4811// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4812// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:024813TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224814 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
4815 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034816 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514817 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074818 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424819 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504820 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224821
4822 HttpRequestInfo request1;
4823 request1.method = "GET";
bncce36dca22015-04-21 22:11:234824 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224825 request1.load_flags = 0;
4826
4827 HttpRequestInfo request2;
4828 request2.method = "GET";
bncce36dca22015-04-21 22:11:234829 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:224830 request2.load_flags = 0;
4831
bncce36dca22015-04-21 22:11:234832 // CONNECT to www.example.org:443 via SPDY.
bncb03b1092016-04-06 11:19:554833 scoped_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234834 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncb03b1092016-04-06 11:19:554835 scoped_ptr<SpdySerializedFrame> conn_resp1(
[email protected]23e482282013-06-14 16:08:024836 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224837
bncce36dca22015-04-21 22:11:234838 // Fetch https://www.example.org/ via HTTP.
4839 const char get1[] =
4840 "GET / HTTP/1.1\r\n"
4841 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224842 "Connection: keep-alive\r\n\r\n";
bncb03b1092016-04-06 11:19:554843 scoped_ptr<SpdySerializedFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024844 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224845 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4846 "Content-Length: 1\r\n\r\n";
bncb03b1092016-04-06 11:19:554847 scoped_ptr<SpdySerializedFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024848 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
bncb03b1092016-04-06 11:19:554849 scoped_ptr<SpdySerializedFrame> wrapped_body1(
[email protected]23e482282013-06-14 16:08:024850 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
bncb03b1092016-04-06 11:19:554851 scoped_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204852 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224853
bncce36dca22015-04-21 22:11:234854 // Fetch https://www.example.org/2 via HTTP.
4855 const char get2[] =
4856 "GET /2 HTTP/1.1\r\n"
4857 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224858 "Connection: keep-alive\r\n\r\n";
bncb03b1092016-04-06 11:19:554859 scoped_ptr<SpdySerializedFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024860 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224861 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4862 "Content-Length: 2\r\n\r\n";
bncb03b1092016-04-06 11:19:554863 scoped_ptr<SpdySerializedFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024864 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
bncb03b1092016-04-06 11:19:554865 scoped_ptr<SpdySerializedFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024866 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224867
4868 MockWrite spdy_writes[] = {
4869 CreateMockWrite(*connect1, 0),
4870 CreateMockWrite(*wrapped_get1, 2),
4871 CreateMockWrite(*wrapped_get2, 5),
4872 };
4873
4874 MockRead spdy_reads[] = {
4875 CreateMockRead(*conn_resp1, 1, ASYNC),
4876 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4877 CreateMockRead(*wrapped_body1, 4, ASYNC),
4878 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4879 CreateMockRead(*wrapped_body2, 7, ASYNC),
4880 MockRead(ASYNC, 0, 8),
4881 };
4882
mmenke11eb5152015-06-09 14:50:504883 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4884 arraysize(spdy_writes));
4885 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224886
4887 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384888 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:504889 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224890 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224892
4893 TestCompletionCallback callback;
4894
[email protected]262eec82013-03-19 21:01:364895 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504896 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224897 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4898 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224899
4900 rv = callback.WaitForResult();
4901 EXPECT_EQ(OK, rv);
4902
4903 LoadTimingInfo load_timing_info;
4904 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4905 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4906
4907 const HttpResponseInfo* response = trans->GetResponseInfo();
4908 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504909 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224910 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4911
4912 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294913 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504914 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224915 trans.reset();
4916
[email protected]262eec82013-03-19 21:01:364917 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504918 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224919 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4920 EXPECT_EQ(ERR_IO_PENDING, rv);
4921
[email protected]f6c63db52013-02-02 00:35:224922 rv = callback.WaitForResult();
4923 EXPECT_EQ(OK, rv);
4924
4925 LoadTimingInfo load_timing_info2;
4926 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4927 TestLoadTimingReused(load_timing_info2);
4928
4929 // The requests should have the same ID.
4930 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4931
[email protected]90499482013-06-01 00:39:504932 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224933}
4934
4935// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4936// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504937TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224938 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034939 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514940 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074941 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:424942 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504943 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224944
4945 HttpRequestInfo request1;
4946 request1.method = "GET";
bncce36dca22015-04-21 22:11:234947 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224948 request1.load_flags = 0;
4949
4950 HttpRequestInfo request2;
4951 request2.method = "GET";
bncce36dca22015-04-21 22:11:234952 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224953 request2.load_flags = 0;
4954
bncce36dca22015-04-21 22:11:234955 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024956 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234957 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncb03b1092016-04-06 11:19:554958 scoped_ptr<SpdySerializedFrame> get1(
bnc38dcd392016-02-09 23:19:494959 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
bncb03b1092016-04-06 11:19:554960 scoped_ptr<SpdySerializedFrame> get_resp1(
[email protected]23e482282013-06-14 16:08:024961 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
bncb03b1092016-04-06 11:19:554962 scoped_ptr<SpdySerializedFrame> body1(
[email protected]23e482282013-06-14 16:08:024963 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:384964 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:224965
bncce36dca22015-04-21 22:11:234966 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024967 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234968 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
bncb03b1092016-04-06 11:19:554969 scoped_ptr<SpdySerializedFrame> get2(
bnc38dcd392016-02-09 23:19:494970 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, true));
bncb03b1092016-04-06 11:19:554971 scoped_ptr<SpdySerializedFrame> get_resp2(
[email protected]23e482282013-06-14 16:08:024972 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
bncb03b1092016-04-06 11:19:554973 scoped_ptr<SpdySerializedFrame> body2(
[email protected]23e482282013-06-14 16:08:024974 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224975
4976 MockWrite spdy_writes[] = {
4977 CreateMockWrite(*get1, 0),
4978 CreateMockWrite(*get2, 3),
4979 };
4980
4981 MockRead spdy_reads[] = {
4982 CreateMockRead(*get_resp1, 1, ASYNC),
4983 CreateMockRead(*body1, 2, ASYNC),
4984 CreateMockRead(*get_resp2, 4, ASYNC),
4985 CreateMockRead(*body2, 5, ASYNC),
4986 MockRead(ASYNC, 0, 6),
4987 };
4988
mmenke11eb5152015-06-09 14:50:504989 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4990 arraysize(spdy_writes));
4991 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224992
4993 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384994 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:504995 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224996
4997 TestCompletionCallback callback;
4998
[email protected]262eec82013-03-19 21:01:364999 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505000 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225001 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505002 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225003
5004 LoadTimingInfo load_timing_info;
5005 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5006 TestLoadTimingNotReused(load_timing_info,
5007 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5008
5009 const HttpResponseInfo* response = trans->GetResponseInfo();
5010 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505011 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:025012 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225013
5014 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295015 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505016 rv = trans->Read(buf.get(), 256, callback.callback());
5017 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225018 // Delete the first request, so the second one can reuse the socket.
5019 trans.reset();
5020
[email protected]262eec82013-03-19 21:01:365021 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:505022 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225023 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505024 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225025
5026 LoadTimingInfo load_timing_info2;
5027 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5028 TestLoadTimingReused(load_timing_info2);
5029
5030 // The requests should have the same ID.
5031 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5032
mmenke11eb5152015-06-09 14:50:505033 rv = trans2->Read(buf.get(), 256, callback.callback());
5034 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225035}
5036
[email protected]2df19bb2010-08-25 20:13:465037// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:025038TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465039 HttpRequestInfo request;
5040 request.method = "GET";
bncce36dca22015-04-21 22:11:235041 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465042 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295043 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465044
[email protected]79cb5c12011-09-12 13:12:045045 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035046 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515047 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075048 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:425049 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275050
[email protected]2df19bb2010-08-25 20:13:465051 // Since we have proxy, should use full url
5052 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235053 MockWrite(
5054 "GET http://www.example.org/ HTTP/1.1\r\n"
5055 "Host: www.example.org\r\n"
5056 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465057
bncce36dca22015-04-21 22:11:235058 // After calling trans->RestartWithAuth(), this is the request we should
5059 // be issuing -- the final header line contains the credentials.
5060 MockWrite(
5061 "GET http://www.example.org/ HTTP/1.1\r\n"
5062 "Host: www.example.org\r\n"
5063 "Proxy-Connection: keep-alive\r\n"
5064 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465065 };
5066
5067 // The proxy responds to the GET with a 407, using a persistent
5068 // connection.
5069 MockRead data_reads1[] = {
5070 // No credentials.
5071 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5072 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5073 MockRead("Proxy-Connection: keep-alive\r\n"),
5074 MockRead("Content-Length: 0\r\n\r\n"),
5075
5076 MockRead("HTTP/1.1 200 OK\r\n"),
5077 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5078 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065079 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465080 };
5081
5082 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5083 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075084 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065085 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465087
[email protected]49639fa2011-12-20 23:22:415088 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465089
[email protected]262eec82013-03-19 21:01:365090 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505091 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505092
[email protected]49639fa2011-12-20 23:22:415093 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:465094 EXPECT_EQ(ERR_IO_PENDING, rv);
5095
5096 rv = callback1.WaitForResult();
5097 EXPECT_EQ(OK, rv);
5098
[email protected]58e32bb2013-01-21 18:23:255099 LoadTimingInfo load_timing_info;
5100 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5101 TestLoadTimingNotReused(load_timing_info,
5102 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5103
[email protected]2df19bb2010-08-25 20:13:465104 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505105 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505106 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:465107 EXPECT_EQ(407, response->headers->response_code());
5108 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:045109 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465110
[email protected]49639fa2011-12-20 23:22:415111 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465112
[email protected]49639fa2011-12-20 23:22:415113 rv = trans->RestartWithAuth(
5114 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:465115 EXPECT_EQ(ERR_IO_PENDING, rv);
5116
5117 rv = callback2.WaitForResult();
5118 EXPECT_EQ(OK, rv);
5119
[email protected]58e32bb2013-01-21 18:23:255120 load_timing_info = LoadTimingInfo();
5121 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5122 // Retrying with HTTP AUTH is considered to be reusing a socket.
5123 TestLoadTimingReused(load_timing_info);
5124
[email protected]2df19bb2010-08-25 20:13:465125 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505126 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:465127
5128 EXPECT_TRUE(response->headers->IsKeepAlive());
5129 EXPECT_EQ(200, response->headers->response_code());
5130 EXPECT_EQ(100, response->headers->GetContentLength());
5131 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5132
5133 // The password prompt info should not be set.
5134 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5135}
5136
[email protected]23e482282013-06-14 16:08:025137void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085138 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425139 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085140 request.method = "GET";
bncce36dca22015-04-21 22:11:235141 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085142 request.load_flags = 0;
5143
[email protected]cb9bf6ca2011-01-28 13:15:275144 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035145 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:425146 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275147
[email protected]c744cf22009-02-27 07:28:085148 // Since we have proxy, should try to establish tunnel.
5149 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175150 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5151 "Host: www.example.org:443\r\n"
5152 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085153 };
5154
5155 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235156 status, MockRead("Content-Length: 10\r\n\r\n"),
5157 // No response body because the test stops reading here.
5158 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085159 };
5160
[email protected]31a2bfe2010-02-09 08:03:395161 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5162 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075163 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085164
[email protected]49639fa2011-12-20 23:22:415165 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085166
[email protected]262eec82013-03-19 21:01:365167 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505168 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505169
[email protected]49639fa2011-12-20 23:22:415170 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425171 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:085172
5173 rv = callback.WaitForResult();
5174 EXPECT_EQ(expected_status, rv);
5175}
5176
[email protected]23e482282013-06-14 16:08:025177void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235178 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085179 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425180 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085181}
5182
[email protected]23e482282013-06-14 16:08:025183TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085184 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5185}
5186
[email protected]23e482282013-06-14 16:08:025187TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085188 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5189}
5190
[email protected]23e482282013-06-14 16:08:025191TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085192 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5193}
5194
[email protected]23e482282013-06-14 16:08:025195TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085196 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5197}
5198
[email protected]23e482282013-06-14 16:08:025199TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085200 ConnectStatusHelper(
5201 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5202}
5203
[email protected]23e482282013-06-14 16:08:025204TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085205 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5206}
5207
[email protected]23e482282013-06-14 16:08:025208TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085209 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5210}
5211
[email protected]23e482282013-06-14 16:08:025212TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085213 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5214}
5215
[email protected]23e482282013-06-14 16:08:025216TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085217 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5218}
5219
[email protected]23e482282013-06-14 16:08:025220TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085221 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5222}
5223
[email protected]23e482282013-06-14 16:08:025224TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085225 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5226}
5227
[email protected]23e482282013-06-14 16:08:025228TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085229 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5230}
5231
[email protected]23e482282013-06-14 16:08:025232TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085233 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5234}
5235
[email protected]23e482282013-06-14 16:08:025236TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085237 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5238}
5239
[email protected]23e482282013-06-14 16:08:025240TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085241 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5242}
5243
[email protected]23e482282013-06-14 16:08:025244TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085245 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5246}
5247
[email protected]0a17aab32014-04-24 03:32:375248TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
5249 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5250}
5251
[email protected]23e482282013-06-14 16:08:025252TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085253 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5254}
5255
[email protected]23e482282013-06-14 16:08:025256TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085257 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5258}
5259
[email protected]23e482282013-06-14 16:08:025260TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085261 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5262}
5263
[email protected]23e482282013-06-14 16:08:025264TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085265 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5266}
5267
[email protected]23e482282013-06-14 16:08:025268TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085269 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5270}
5271
[email protected]23e482282013-06-14 16:08:025272TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085273 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5274}
5275
[email protected]23e482282013-06-14 16:08:025276TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085277 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5278}
5279
[email protected]23e482282013-06-14 16:08:025280TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085281 ConnectStatusHelperWithExpectedStatus(
5282 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545283 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085284}
5285
[email protected]23e482282013-06-14 16:08:025286TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085287 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5288}
5289
[email protected]23e482282013-06-14 16:08:025290TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085291 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5292}
5293
[email protected]23e482282013-06-14 16:08:025294TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085295 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5296}
5297
[email protected]23e482282013-06-14 16:08:025298TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085299 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5300}
5301
[email protected]23e482282013-06-14 16:08:025302TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085303 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5304}
5305
[email protected]23e482282013-06-14 16:08:025306TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085307 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5308}
5309
[email protected]23e482282013-06-14 16:08:025310TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085311 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5312}
5313
[email protected]23e482282013-06-14 16:08:025314TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085315 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5316}
5317
[email protected]23e482282013-06-14 16:08:025318TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085319 ConnectStatusHelper(
5320 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5321}
5322
[email protected]23e482282013-06-14 16:08:025323TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085324 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5325}
5326
[email protected]23e482282013-06-14 16:08:025327TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085328 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5329}
5330
[email protected]23e482282013-06-14 16:08:025331TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085332 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5333}
5334
[email protected]23e482282013-06-14 16:08:025335TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085336 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5337}
5338
[email protected]23e482282013-06-14 16:08:025339TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085340 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5341}
5342
[email protected]23e482282013-06-14 16:08:025343TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085344 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5345}
5346
[email protected]23e482282013-06-14 16:08:025347TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085348 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5349}
5350
[email protected]038e9a32008-10-08 22:40:165351// Test the flow when both the proxy server AND origin server require
5352// authentication. Again, this uses basic auth for both since that is
5353// the simplest to mock.
[email protected]23e482282013-06-14 16:08:025354TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275355 HttpRequestInfo request;
5356 request.method = "GET";
bncce36dca22015-04-21 22:11:235357 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275358 request.load_flags = 0;
5359
[email protected]038e9a32008-10-08 22:40:165360 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035361 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:425362 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075363
5364 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415365 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:165366
[email protected]f9ee6b52008-11-08 06:46:235367 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235368 MockWrite(
5369 "GET http://www.example.org/ HTTP/1.1\r\n"
5370 "Host: www.example.org\r\n"
5371 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235372 };
5373
[email protected]038e9a32008-10-08 22:40:165374 MockRead data_reads1[] = {
5375 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5376 // Give a couple authenticate options (only the middle one is actually
5377 // supported).
[email protected]22927ad2009-09-21 19:56:195378 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165379 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5380 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5381 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5382 // Large content-length -- won't matter, as connection will be reset.
5383 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065384 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165385 };
5386
5387 // After calling trans->RestartWithAuth() the first time, this is the
5388 // request we should be issuing -- the final header line contains the
5389 // proxy's credentials.
5390 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235391 MockWrite(
5392 "GET http://www.example.org/ HTTP/1.1\r\n"
5393 "Host: www.example.org\r\n"
5394 "Proxy-Connection: keep-alive\r\n"
5395 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165396 };
5397
5398 // Now the proxy server lets the request pass through to origin server.
5399 // The origin server responds with a 401.
5400 MockRead data_reads2[] = {
5401 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5402 // Note: We are using the same realm-name as the proxy server. This is
5403 // completely valid, as realms are unique across hosts.
5404 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5405 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5406 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065407 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165408 };
5409
5410 // After calling trans->RestartWithAuth() the second time, we should send
5411 // the credentials for both the proxy and origin server.
5412 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235413 MockWrite(
5414 "GET http://www.example.org/ HTTP/1.1\r\n"
5415 "Host: www.example.org\r\n"
5416 "Proxy-Connection: keep-alive\r\n"
5417 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5418 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165419 };
5420
5421 // Lastly we get the desired content.
5422 MockRead data_reads3[] = {
5423 MockRead("HTTP/1.0 200 OK\r\n"),
5424 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5425 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065426 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165427 };
5428
[email protected]31a2bfe2010-02-09 08:03:395429 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5430 data_writes1, arraysize(data_writes1));
5431 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5432 data_writes2, arraysize(data_writes2));
5433 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5434 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075435 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5436 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5437 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165438
[email protected]49639fa2011-12-20 23:22:415439 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165440
[email protected]49639fa2011-12-20 23:22:415441 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425442 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165443
5444 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425445 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165446
[email protected]1c773ea12009-04-28 19:58:425447 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505448 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045449 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165450
[email protected]49639fa2011-12-20 23:22:415451 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165452
[email protected]49639fa2011-12-20 23:22:415453 rv = trans->RestartWithAuth(
5454 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425455 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165456
5457 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425458 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165459
5460 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505461 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045462 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165463
[email protected]49639fa2011-12-20 23:22:415464 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165465
[email protected]49639fa2011-12-20 23:22:415466 rv = trans->RestartWithAuth(
5467 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425468 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165469
5470 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425471 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165472
5473 response = trans->GetResponseInfo();
5474 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5475 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165476}
[email protected]4ddaf2502008-10-23 18:26:195477
[email protected]ea9dc9a2009-09-05 00:43:325478// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5479// can't hook into its internals to cause it to generate predictable NTLM
5480// authorization headers.
5481#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295482// The NTLM authentication unit tests were generated by capturing the HTTP
5483// requests and responses using Fiddler 2 and inspecting the generated random
5484// bytes in the debugger.
5485
5486// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:025487TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425488 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245489 request.method = "GET";
5490 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545491
5492 // Ensure load is not disrupted by flags which suppress behaviour specific
5493 // to other auth schemes.
5494 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245495
[email protected]cb9bf6ca2011-01-28 13:15:275496 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5497 MockGetHostName);
mmenkee65e7af2015-10-13 17:16:425498 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275499
[email protected]3f918782009-02-28 01:29:245500 MockWrite data_writes1[] = {
5501 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5502 "Host: 172.22.68.17\r\n"
5503 "Connection: keep-alive\r\n\r\n"),
5504 };
5505
5506 MockRead data_reads1[] = {
5507 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045508 // Negotiate and NTLM are often requested together. However, we only want
5509 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5510 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245511 MockRead("WWW-Authenticate: NTLM\r\n"),
5512 MockRead("Connection: close\r\n"),
5513 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365514 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245515 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065516 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245517 };
5518
5519 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225520 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:245521 // request we should be issuing -- the final header line contains a Type
5522 // 1 message.
5523 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5524 "Host: 172.22.68.17\r\n"
5525 "Connection: keep-alive\r\n"
5526 "Authorization: NTLM "
5527 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5528
5529 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5530 // (the credentials for the origin server). The second request continues
5531 // on the same connection.
5532 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5533 "Host: 172.22.68.17\r\n"
5534 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:295535 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5536 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5537 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5538 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5539 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245540 };
5541
5542 MockRead data_reads2[] = {
5543 // The origin server responds with a Type 2 message.
5544 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5545 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295546 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245547 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5548 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5549 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5550 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5551 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5552 "BtAAAAAAA=\r\n"),
5553 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365554 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245555 MockRead("You are not authorized to view this page\r\n"),
5556
5557 // Lastly we get the desired content.
5558 MockRead("HTTP/1.1 200 OK\r\n"),
5559 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5560 MockRead("Content-Length: 13\r\n\r\n"),
5561 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065562 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245563 };
5564
[email protected]31a2bfe2010-02-09 08:03:395565 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5566 data_writes1, arraysize(data_writes1));
5567 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5568 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075569 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5570 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245571
[email protected]49639fa2011-12-20 23:22:415572 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245573
[email protected]262eec82013-03-19 21:01:365574 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505575 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505576
[email protected]49639fa2011-12-20 23:22:415577 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425578 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245579
5580 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425581 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245582
[email protected]0757e7702009-03-27 04:00:225583 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5584
[email protected]1c773ea12009-04-28 19:58:425585 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045586 ASSERT_FALSE(response == NULL);
5587 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245588
[email protected]49639fa2011-12-20 23:22:415589 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255590
[email protected]f3cf9802011-10-28 18:44:585591 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415592 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:255593 EXPECT_EQ(ERR_IO_PENDING, rv);
5594
5595 rv = callback2.WaitForResult();
5596 EXPECT_EQ(OK, rv);
5597
5598 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5599
5600 response = trans->GetResponseInfo();
5601 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:255602 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5603
[email protected]49639fa2011-12-20 23:22:415604 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245605
[email protected]49639fa2011-12-20 23:22:415606 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425607 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245608
[email protected]0757e7702009-03-27 04:00:225609 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425610 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245611
5612 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505613 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:245614 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5615 EXPECT_EQ(13, response->headers->GetContentLength());
5616}
5617
[email protected]385a4672009-03-11 22:21:295618// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:025619TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425620 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295621 request.method = "GET";
5622 request.url = GURL("http://172.22.68.17/kids/login.aspx");
5623 request.load_flags = 0;
5624
[email protected]cb9bf6ca2011-01-28 13:15:275625 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5626 MockGetHostName);
mmenkee65e7af2015-10-13 17:16:425627 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275628
[email protected]385a4672009-03-11 22:21:295629 MockWrite data_writes1[] = {
5630 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5631 "Host: 172.22.68.17\r\n"
5632 "Connection: keep-alive\r\n\r\n"),
5633 };
5634
5635 MockRead data_reads1[] = {
5636 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045637 // Negotiate and NTLM are often requested together. However, we only want
5638 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5639 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:295640 MockRead("WWW-Authenticate: NTLM\r\n"),
5641 MockRead("Connection: close\r\n"),
5642 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365643 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295644 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065645 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295646 };
5647
5648 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225649 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295650 // request we should be issuing -- the final header line contains a Type
5651 // 1 message.
5652 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5653 "Host: 172.22.68.17\r\n"
5654 "Connection: keep-alive\r\n"
5655 "Authorization: NTLM "
5656 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5657
5658 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5659 // (the credentials for the origin server). The second request continues
5660 // on the same connection.
5661 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5662 "Host: 172.22.68.17\r\n"
5663 "Connection: keep-alive\r\n"
5664 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5665 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5666 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
5667 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
5668 "4Ww7b7E=\r\n\r\n"),
5669 };
5670
5671 MockRead data_reads2[] = {
5672 // The origin server responds with a Type 2 message.
5673 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5674 MockRead("WWW-Authenticate: NTLM "
5675 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
5676 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5677 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5678 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5679 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5680 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5681 "BtAAAAAAA=\r\n"),
5682 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365683 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295684 MockRead("You are not authorized to view this page\r\n"),
5685
5686 // Wrong password.
5687 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:295688 MockRead("WWW-Authenticate: NTLM\r\n"),
5689 MockRead("Connection: close\r\n"),
5690 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365691 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295692 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065693 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295694 };
5695
5696 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:225697 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295698 // request we should be issuing -- the final header line contains a Type
5699 // 1 message.
5700 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5701 "Host: 172.22.68.17\r\n"
5702 "Connection: keep-alive\r\n"
5703 "Authorization: NTLM "
5704 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5705
5706 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5707 // (the credentials for the origin server). The second request continues
5708 // on the same connection.
5709 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5710 "Host: 172.22.68.17\r\n"
5711 "Connection: keep-alive\r\n"
5712 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5713 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5714 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
5715 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
5716 "+4MUm7c=\r\n\r\n"),
5717 };
5718
5719 MockRead data_reads3[] = {
5720 // The origin server responds with a Type 2 message.
5721 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5722 MockRead("WWW-Authenticate: NTLM "
5723 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
5724 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5725 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5726 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5727 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5728 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5729 "BtAAAAAAA=\r\n"),
5730 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365731 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295732 MockRead("You are not authorized to view this page\r\n"),
5733
5734 // Lastly we get the desired content.
5735 MockRead("HTTP/1.1 200 OK\r\n"),
5736 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5737 MockRead("Content-Length: 13\r\n\r\n"),
5738 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065739 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:295740 };
5741
[email protected]31a2bfe2010-02-09 08:03:395742 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5743 data_writes1, arraysize(data_writes1));
5744 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5745 data_writes2, arraysize(data_writes2));
5746 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5747 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075748 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5749 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5750 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:295751
[email protected]49639fa2011-12-20 23:22:415752 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:295753
[email protected]262eec82013-03-19 21:01:365754 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505755 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505756
[email protected]49639fa2011-12-20 23:22:415757 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425758 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295759
5760 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425761 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295762
[email protected]0757e7702009-03-27 04:00:225763 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:295764
[email protected]1c773ea12009-04-28 19:58:425765 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505766 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045767 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:295768
[email protected]49639fa2011-12-20 23:22:415769 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:295770
[email protected]0757e7702009-03-27 04:00:225771 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:585772 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:415773 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425774 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295775
[email protected]10af5fe72011-01-31 16:17:255776 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425777 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295778
[email protected]0757e7702009-03-27 04:00:225779 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415780 TestCompletionCallback callback3;
5781 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425782 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:255783 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425784 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225785 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5786
5787 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045788 ASSERT_FALSE(response == NULL);
5789 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:225790
[email protected]49639fa2011-12-20 23:22:415791 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:225792
5793 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:585794 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415795 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:255796 EXPECT_EQ(ERR_IO_PENDING, rv);
5797
5798 rv = callback4.WaitForResult();
5799 EXPECT_EQ(OK, rv);
5800
5801 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5802
[email protected]49639fa2011-12-20 23:22:415803 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:255804
5805 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:415806 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:425807 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225808
5809 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425810 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225811
[email protected]385a4672009-03-11 22:21:295812 response = trans->GetResponseInfo();
5813 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5814 EXPECT_EQ(13, response->headers->GetContentLength());
5815}
[email protected]ea9dc9a2009-09-05 00:43:325816#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:295817
[email protected]4ddaf2502008-10-23 18:26:195818// Test reading a server response which has only headers, and no body.
5819// After some maximum number of bytes is consumed, the transaction should
5820// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:025821TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:425822 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:195823 request.method = "GET";
bncce36dca22015-04-21 22:11:235824 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:195825 request.load_flags = 0;
5826
mmenkee65e7af2015-10-13 17:16:425827 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275828 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415829 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275830
[email protected]b75b7b2f2009-10-06 00:54:535831 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:435832 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:535833 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:195834
5835 MockRead data_reads[] = {
5836 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065837 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:195838 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:065839 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:195840 };
[email protected]31a2bfe2010-02-09 08:03:395841 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075842 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:195843
[email protected]49639fa2011-12-20 23:22:415844 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195845
[email protected]49639fa2011-12-20 23:22:415846 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425847 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195848
5849 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425850 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195851}
[email protected]f4e426b2008-11-05 00:24:495852
5853// Make sure that we don't try to reuse a TCPClientSocket when failing to
5854// establish tunnel.
5855// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025856TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235857 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275858 HttpRequestInfo request;
5859 request.method = "GET";
bncce36dca22015-04-21 22:11:235860 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275861 request.load_flags = 0;
5862
[email protected]f4e426b2008-11-05 00:24:495863 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035864 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:015865
mmenkee65e7af2015-10-13 17:16:425866 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495867
[email protected]262eec82013-03-19 21:01:365868 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505869 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495870
[email protected]f4e426b2008-11-05 00:24:495871 // Since we have proxy, should try to establish tunnel.
5872 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175873 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5874 "Host: www.example.org:443\r\n"
5875 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495876 };
5877
[email protected]77848d12008-11-14 00:00:225878 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495879 // connection. Usually a proxy would return 501 (not implemented),
5880 // or 200 (tunnel established).
5881 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:235882 MockRead("HTTP/1.1 404 Not Found\r\n"),
5883 MockRead("Content-Length: 10\r\n\r\n"),
5884 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:495885 };
5886
[email protected]31a2bfe2010-02-09 08:03:395887 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5888 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075889 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495890
[email protected]49639fa2011-12-20 23:22:415891 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495892
[email protected]49639fa2011-12-20 23:22:415893 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425894 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495895
5896 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425897 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495898
[email protected]b4404c02009-04-10 16:38:525899 // Empty the current queue. This is necessary because idle sockets are
5900 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345901 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525902
[email protected]f4e426b2008-11-05 00:24:495903 // We now check to make sure the TCPClientSocket was not added back to
5904 // the pool.
[email protected]90499482013-06-01 00:39:505905 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495906 trans.reset();
[email protected]2da659e2013-05-23 20:51:345907 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495908 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505909 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495910}
[email protected]372d34a2008-11-05 21:30:515911
[email protected]1b157c02009-04-21 01:55:405912// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025913TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425914 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405915 request.method = "GET";
bncce36dca22015-04-21 22:11:235916 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405917 request.load_flags = 0;
5918
mmenkee65e7af2015-10-13 17:16:425919 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275920
[email protected]262eec82013-03-19 21:01:365921 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275923
[email protected]1b157c02009-04-21 01:55:405924 MockRead data_reads[] = {
5925 // A part of the response body is received with the response headers.
5926 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5927 // The rest of the response body is received in two parts.
5928 MockRead("lo"),
5929 MockRead(" world"),
5930 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065931 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405932 };
5933
[email protected]31a2bfe2010-02-09 08:03:395934 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075935 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405936
[email protected]49639fa2011-12-20 23:22:415937 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405938
[email protected]49639fa2011-12-20 23:22:415939 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425940 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405941
5942 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425943 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405944
[email protected]1c773ea12009-04-28 19:58:425945 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505946 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405947
[email protected]90499482013-06-01 00:39:505948 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405949 std::string status_line = response->headers->GetStatusLine();
5950 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5951
[email protected]90499482013-06-01 00:39:505952 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405953
5954 std::string response_data;
5955 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425956 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405957 EXPECT_EQ("hello world", response_data);
5958
5959 // Empty the current queue. This is necessary because idle sockets are
5960 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345961 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405962
5963 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505964 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405965}
5966
[email protected]76a505b2010-08-25 06:23:005967// Make sure that we recycle a SSL socket after reading all of the response
5968// body.
[email protected]23e482282013-06-14 16:08:025969TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005970 HttpRequestInfo request;
5971 request.method = "GET";
bncce36dca22015-04-21 22:11:235972 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005973 request.load_flags = 0;
5974
5975 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235976 MockWrite(
5977 "GET / HTTP/1.1\r\n"
5978 "Host: www.example.org\r\n"
5979 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005980 };
5981
5982 MockRead data_reads[] = {
5983 MockRead("HTTP/1.1 200 OK\r\n"),
5984 MockRead("Content-Length: 11\r\n\r\n"),
5985 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065986 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005987 };
5988
[email protected]8ddf8322012-02-23 18:08:065989 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005991
5992 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5993 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075994 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005995
[email protected]49639fa2011-12-20 23:22:415996 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005997
mmenkee65e7af2015-10-13 17:16:425998 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365999 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506000 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006001
[email protected]49639fa2011-12-20 23:22:416002 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006003
6004 EXPECT_EQ(ERR_IO_PENDING, rv);
6005 EXPECT_EQ(OK, callback.WaitForResult());
6006
6007 const HttpResponseInfo* response = trans->GetResponseInfo();
6008 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506009 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:006010 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6011
[email protected]90499482013-06-01 00:39:506012 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006013
6014 std::string response_data;
6015 rv = ReadTransaction(trans.get(), &response_data);
6016 EXPECT_EQ(OK, rv);
6017 EXPECT_EQ("hello world", response_data);
6018
6019 // Empty the current queue. This is necessary because idle sockets are
6020 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:346021 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006022
6023 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506024 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006025}
6026
6027// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6028// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:026029TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006030 HttpRequestInfo request;
6031 request.method = "GET";
bncce36dca22015-04-21 22:11:236032 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006033 request.load_flags = 0;
6034
6035 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236036 MockWrite(
6037 "GET / HTTP/1.1\r\n"
6038 "Host: www.example.org\r\n"
6039 "Connection: keep-alive\r\n\r\n"),
6040 MockWrite(
6041 "GET / HTTP/1.1\r\n"
6042 "Host: www.example.org\r\n"
6043 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006044 };
6045
6046 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426047 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6048 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006049
[email protected]8ddf8322012-02-23 18:08:066050 SSLSocketDataProvider ssl(ASYNC, OK);
6051 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076052 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6053 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006054
6055 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6056 data_writes, arraysize(data_writes));
6057 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6058 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076059 session_deps_.socket_factory->AddSocketDataProvider(&data);
6060 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006061
[email protected]49639fa2011-12-20 23:22:416062 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006063
mmenkee65e7af2015-10-13 17:16:426064 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:366065 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506066 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006067
[email protected]49639fa2011-12-20 23:22:416068 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006069
6070 EXPECT_EQ(ERR_IO_PENDING, rv);
6071 EXPECT_EQ(OK, callback.WaitForResult());
6072
6073 const HttpResponseInfo* response = trans->GetResponseInfo();
6074 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506075 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:006076 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6077
[email protected]90499482013-06-01 00:39:506078 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006079
6080 std::string response_data;
6081 rv = ReadTransaction(trans.get(), &response_data);
6082 EXPECT_EQ(OK, rv);
6083 EXPECT_EQ("hello world", response_data);
6084
6085 // Empty the current queue. This is necessary because idle sockets are
6086 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:346087 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006088
6089 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506090 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006091
6092 // Now start the second transaction, which should reuse the previous socket.
6093
[email protected]90499482013-06-01 00:39:506094 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006095
[email protected]49639fa2011-12-20 23:22:416096 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006097
6098 EXPECT_EQ(ERR_IO_PENDING, rv);
6099 EXPECT_EQ(OK, callback.WaitForResult());
6100
6101 response = trans->GetResponseInfo();
6102 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506103 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:006104 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6105
[email protected]90499482013-06-01 00:39:506106 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006107
6108 rv = ReadTransaction(trans.get(), &response_data);
6109 EXPECT_EQ(OK, rv);
6110 EXPECT_EQ("hello world", response_data);
6111
6112 // Empty the current queue. This is necessary because idle sockets are
6113 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:346114 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006115
6116 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506117 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006118}
6119
[email protected]b4404c02009-04-10 16:38:526120// Make sure that we recycle a socket after a zero-length response.
6121// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:026122TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426123 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526124 request.method = "GET";
bncce36dca22015-04-21 22:11:236125 request.url = GURL(
6126 "http://www.example.org/csi?v=3&s=web&action=&"
6127 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6128 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6129 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526130 request.load_flags = 0;
6131
mmenkee65e7af2015-10-13 17:16:426132 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276133
[email protected]b4404c02009-04-10 16:38:526134 MockRead data_reads[] = {
6135 MockRead("HTTP/1.1 204 No Content\r\n"
6136 "Content-Length: 0\r\n"
6137 "Content-Type: text/html\r\n\r\n"),
6138 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066139 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526140 };
6141
[email protected]31a2bfe2010-02-09 08:03:396142 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076143 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526144
mmenkecc2298e2015-12-07 18:20:186145 // Transaction must be created after the MockReads, so it's destroyed before
6146 // them.
6147 scoped_ptr<HttpTransaction> trans(
6148 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6149
[email protected]49639fa2011-12-20 23:22:416150 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526151
[email protected]49639fa2011-12-20 23:22:416152 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426153 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:526154
6155 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426156 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:526157
[email protected]1c773ea12009-04-28 19:58:426158 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506159 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:526160
[email protected]90499482013-06-01 00:39:506161 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:526162 std::string status_line = response->headers->GetStatusLine();
6163 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6164
[email protected]90499482013-06-01 00:39:506165 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526166
6167 std::string response_data;
6168 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426169 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:526170 EXPECT_EQ("", response_data);
6171
6172 // Empty the current queue. This is necessary because idle sockets are
6173 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:346174 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526175
6176 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506177 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526178}
6179
[email protected]23e482282013-06-14 16:08:026180TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
olli.raula6df48b2a2015-11-26 07:40:226181 std::vector<scoped_ptr<UploadElementReader>> element_readers;
6182 element_readers.push_back(
6183 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
6184 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276185
[email protected]1c773ea12009-04-28 19:58:426186 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516187 // Transaction 1: a GET request that succeeds. The socket is recycled
6188 // after use.
6189 request[0].method = "GET";
6190 request[0].url = GURL("http://www.google.com/");
6191 request[0].load_flags = 0;
6192 // Transaction 2: a POST request. Reuses the socket kept alive from
6193 // transaction 1. The first attempts fails when writing the POST data.
6194 // This causes the transaction to retry with a new socket. The second
6195 // attempt succeeds.
6196 request[1].method = "POST";
6197 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276198 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516199 request[1].load_flags = 0;
6200
mmenkee65e7af2015-10-13 17:16:426201 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516202
6203 // The first socket is used for transaction 1 and the first attempt of
6204 // transaction 2.
6205
6206 // The response of transaction 1.
6207 MockRead data_reads1[] = {
6208 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6209 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066210 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516211 };
6212 // The mock write results of transaction 1 and the first attempt of
6213 // transaction 2.
6214 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066215 MockWrite(SYNCHRONOUS, 64), // GET
6216 MockWrite(SYNCHRONOUS, 93), // POST
6217 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516218 };
[email protected]31a2bfe2010-02-09 08:03:396219 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6220 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516221
6222 // The second socket is used for the second attempt of transaction 2.
6223
6224 // The response of transaction 2.
6225 MockRead data_reads2[] = {
6226 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6227 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066228 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516229 };
6230 // The mock write results of the second attempt of transaction 2.
6231 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066232 MockWrite(SYNCHRONOUS, 93), // POST
6233 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516234 };
[email protected]31a2bfe2010-02-09 08:03:396235 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6236 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516237
[email protected]bb88e1d32013-05-03 23:11:076238 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6239 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516240
thestig9d3bb0c2015-01-24 00:49:516241 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516242 "hello world", "welcome"
6243 };
6244
6245 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:426246 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:516248
[email protected]49639fa2011-12-20 23:22:416249 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516250
[email protected]49639fa2011-12-20 23:22:416251 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426252 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:516253
6254 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426255 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516256
[email protected]1c773ea12009-04-28 19:58:426257 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506258 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:516259
[email protected]90499482013-06-01 00:39:506260 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:516261 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6262
6263 std::string response_data;
6264 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426265 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516266 EXPECT_EQ(kExpectedResponseData[i], response_data);
6267 }
6268}
[email protected]f9ee6b52008-11-08 06:46:236269
6270// Test the request-challenge-retry sequence for basic auth when there is
6271// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166272// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:026273TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426274 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236275 request.method = "GET";
bncce36dca22015-04-21 22:11:236276 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416277 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296278
mmenkee65e7af2015-10-13 17:16:426279 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276280 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416281 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276282
[email protected]a97cca42009-08-14 01:00:296283 // The password contains an escaped character -- for this test to pass it
6284 // will need to be unescaped by HttpNetworkTransaction.
6285 EXPECT_EQ("b%40r", request.url.password());
6286
[email protected]f9ee6b52008-11-08 06:46:236287 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236288 MockWrite(
6289 "GET / HTTP/1.1\r\n"
6290 "Host: www.example.org\r\n"
6291 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236292 };
6293
6294 MockRead data_reads1[] = {
6295 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6296 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6297 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066298 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236299 };
6300
[email protected]2262e3a2012-05-22 16:08:166301 // After the challenge above, the transaction will be restarted using the
6302 // identity from the url (foo, b@r) to answer the challenge.
6303 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236304 MockWrite(
6305 "GET / HTTP/1.1\r\n"
6306 "Host: www.example.org\r\n"
6307 "Connection: keep-alive\r\n"
6308 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166309 };
6310
6311 MockRead data_reads2[] = {
6312 MockRead("HTTP/1.0 200 OK\r\n"),
6313 MockRead("Content-Length: 100\r\n\r\n"),
6314 MockRead(SYNCHRONOUS, OK),
6315 };
6316
[email protected]31a2bfe2010-02-09 08:03:396317 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6318 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166319 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6320 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076321 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6322 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236323
[email protected]49639fa2011-12-20 23:22:416324 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:416325 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426326 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236327 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426328 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:166329 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6330
6331 TestCompletionCallback callback2;
6332 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6333 EXPECT_EQ(ERR_IO_PENDING, rv);
6334 rv = callback2.WaitForResult();
6335 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226336 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6337
[email protected]2262e3a2012-05-22 16:08:166338 const HttpResponseInfo* response = trans->GetResponseInfo();
6339 ASSERT_TRUE(response != NULL);
6340
6341 // There is no challenge info, since the identity in URL worked.
6342 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6343
6344 EXPECT_EQ(100, response->headers->GetContentLength());
6345
6346 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:346347 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166348}
6349
6350// Test the request-challenge-retry sequence for basic auth when there is an
6351// incorrect identity in the URL. The identity from the URL should be used only
6352// once.
[email protected]23e482282013-06-14 16:08:026353TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166354 HttpRequestInfo request;
6355 request.method = "GET";
6356 // Note: the URL has a username:password in it. The password "baz" is
6357 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236358 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166359
6360 request.load_flags = LOAD_NORMAL;
6361
mmenkee65e7af2015-10-13 17:16:426362 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:166363 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:166365
6366 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236367 MockWrite(
6368 "GET / HTTP/1.1\r\n"
6369 "Host: www.example.org\r\n"
6370 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166371 };
6372
6373 MockRead data_reads1[] = {
6374 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6375 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6376 MockRead("Content-Length: 10\r\n\r\n"),
6377 MockRead(SYNCHRONOUS, ERR_FAILED),
6378 };
6379
6380 // After the challenge above, the transaction will be restarted using the
6381 // identity from the url (foo, baz) to answer the challenge.
6382 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236383 MockWrite(
6384 "GET / HTTP/1.1\r\n"
6385 "Host: www.example.org\r\n"
6386 "Connection: keep-alive\r\n"
6387 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166388 };
6389
6390 MockRead data_reads2[] = {
6391 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6392 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6393 MockRead("Content-Length: 10\r\n\r\n"),
6394 MockRead(SYNCHRONOUS, ERR_FAILED),
6395 };
6396
6397 // After the challenge above, the transaction will be restarted using the
6398 // identity supplied by the user (foo, bar) to answer the challenge.
6399 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236400 MockWrite(
6401 "GET / HTTP/1.1\r\n"
6402 "Host: www.example.org\r\n"
6403 "Connection: keep-alive\r\n"
6404 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166405 };
6406
6407 MockRead data_reads3[] = {
6408 MockRead("HTTP/1.0 200 OK\r\n"),
6409 MockRead("Content-Length: 100\r\n\r\n"),
6410 MockRead(SYNCHRONOUS, OK),
6411 };
6412
6413 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6414 data_writes1, arraysize(data_writes1));
6415 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6416 data_writes2, arraysize(data_writes2));
6417 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6418 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076419 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6420 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6421 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166422
6423 TestCompletionCallback callback1;
6424
6425 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6426 EXPECT_EQ(ERR_IO_PENDING, rv);
6427
6428 rv = callback1.WaitForResult();
6429 EXPECT_EQ(OK, rv);
6430
6431 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6432 TestCompletionCallback callback2;
6433 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6434 EXPECT_EQ(ERR_IO_PENDING, rv);
6435 rv = callback2.WaitForResult();
6436 EXPECT_EQ(OK, rv);
6437 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6438
6439 const HttpResponseInfo* response = trans->GetResponseInfo();
6440 ASSERT_TRUE(response != NULL);
6441 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6442
6443 TestCompletionCallback callback3;
6444 rv = trans->RestartWithAuth(
6445 AuthCredentials(kFoo, kBar), callback3.callback());
6446 EXPECT_EQ(ERR_IO_PENDING, rv);
6447 rv = callback3.WaitForResult();
6448 EXPECT_EQ(OK, rv);
6449 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6450
6451 response = trans->GetResponseInfo();
6452 ASSERT_TRUE(response != NULL);
6453
6454 // There is no challenge info, since the identity worked.
6455 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6456
6457 EXPECT_EQ(100, response->headers->GetContentLength());
6458
[email protected]ea9dc9a2009-09-05 00:43:326459 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:346460 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326461}
6462
[email protected]2217aa22013-10-11 03:03:546463
6464// Test the request-challenge-retry sequence for basic auth when there is a
6465// correct identity in the URL, but its use is being suppressed. The identity
6466// from the URL should never be used.
6467TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
6468 HttpRequestInfo request;
6469 request.method = "GET";
bncce36dca22015-04-21 22:11:236470 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546471 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6472
mmenkee65e7af2015-10-13 17:16:426473 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:546474 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416475 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:546476
6477 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236478 MockWrite(
6479 "GET / HTTP/1.1\r\n"
6480 "Host: www.example.org\r\n"
6481 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546482 };
6483
6484 MockRead data_reads1[] = {
6485 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6486 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6487 MockRead("Content-Length: 10\r\n\r\n"),
6488 MockRead(SYNCHRONOUS, ERR_FAILED),
6489 };
6490
6491 // After the challenge above, the transaction will be restarted using the
6492 // identity supplied by the user, not the one in the URL, to answer the
6493 // challenge.
6494 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236495 MockWrite(
6496 "GET / HTTP/1.1\r\n"
6497 "Host: www.example.org\r\n"
6498 "Connection: keep-alive\r\n"
6499 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546500 };
6501
6502 MockRead data_reads3[] = {
6503 MockRead("HTTP/1.0 200 OK\r\n"),
6504 MockRead("Content-Length: 100\r\n\r\n"),
6505 MockRead(SYNCHRONOUS, OK),
6506 };
6507
6508 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6509 data_writes1, arraysize(data_writes1));
6510 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6511 data_writes3, arraysize(data_writes3));
6512 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6513 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6514
6515 TestCompletionCallback callback1;
6516 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6517 EXPECT_EQ(ERR_IO_PENDING, rv);
6518 rv = callback1.WaitForResult();
6519 EXPECT_EQ(OK, rv);
6520 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6521
6522 const HttpResponseInfo* response = trans->GetResponseInfo();
6523 ASSERT_TRUE(response != NULL);
6524 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6525
6526 TestCompletionCallback callback3;
6527 rv = trans->RestartWithAuth(
6528 AuthCredentials(kFoo, kBar), callback3.callback());
6529 EXPECT_EQ(ERR_IO_PENDING, rv);
6530 rv = callback3.WaitForResult();
6531 EXPECT_EQ(OK, rv);
6532 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6533
6534 response = trans->GetResponseInfo();
6535 ASSERT_TRUE(response != NULL);
6536
6537 // There is no challenge info, since the identity worked.
6538 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6539 EXPECT_EQ(100, response->headers->GetContentLength());
6540
6541 // Empty the current queue.
6542 base::MessageLoop::current()->RunUntilIdle();
6543}
6544
[email protected]f9ee6b52008-11-08 06:46:236545// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:026546TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
mmenkee65e7af2015-10-13 17:16:426547 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:236548
6549 // Transaction 1: authenticate (foo, bar) on MyRealm1
6550 {
[email protected]1c773ea12009-04-28 19:58:426551 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236552 request.method = "GET";
bncce36dca22015-04-21 22:11:236553 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:236554 request.load_flags = 0;
6555
[email protected]262eec82013-03-19 21:01:366556 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506557 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276558
[email protected]f9ee6b52008-11-08 06:46:236559 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236560 MockWrite(
6561 "GET /x/y/z HTTP/1.1\r\n"
6562 "Host: www.example.org\r\n"
6563 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236564 };
6565
6566 MockRead data_reads1[] = {
6567 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6568 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6569 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066570 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236571 };
6572
6573 // Resend with authorization (username=foo, password=bar)
6574 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236575 MockWrite(
6576 "GET /x/y/z HTTP/1.1\r\n"
6577 "Host: www.example.org\r\n"
6578 "Connection: keep-alive\r\n"
6579 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236580 };
6581
6582 // Sever accepts the authorization.
6583 MockRead data_reads2[] = {
6584 MockRead("HTTP/1.0 200 OK\r\n"),
6585 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066586 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236587 };
6588
[email protected]31a2bfe2010-02-09 08:03:396589 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6590 data_writes1, arraysize(data_writes1));
6591 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6592 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076593 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6594 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236595
[email protected]49639fa2011-12-20 23:22:416596 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236597
[email protected]49639fa2011-12-20 23:22:416598 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426599 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236600
6601 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426602 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236603
[email protected]1c773ea12009-04-28 19:58:426604 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506605 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046606 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236607
[email protected]49639fa2011-12-20 23:22:416608 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236609
[email protected]49639fa2011-12-20 23:22:416610 rv = trans->RestartWithAuth(
6611 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426612 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236613
6614 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426615 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236616
6617 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506618 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236619 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6620 EXPECT_EQ(100, response->headers->GetContentLength());
6621 }
6622
6623 // ------------------------------------------------------------------------
6624
6625 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
6626 {
[email protected]1c773ea12009-04-28 19:58:426627 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236628 request.method = "GET";
6629 // Note that Transaction 1 was at /x/y/z, so this is in the same
6630 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:236631 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:236632 request.load_flags = 0;
6633
[email protected]262eec82013-03-19 21:01:366634 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506635 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276636
[email protected]f9ee6b52008-11-08 06:46:236637 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236638 MockWrite(
6639 "GET /x/y/a/b HTTP/1.1\r\n"
6640 "Host: www.example.org\r\n"
6641 "Connection: keep-alive\r\n"
6642 // Send preemptive authorization for MyRealm1
6643 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236644 };
6645
6646 // The server didn't like the preemptive authorization, and
6647 // challenges us for a different realm (MyRealm2).
6648 MockRead data_reads1[] = {
6649 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6650 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
6651 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066652 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236653 };
6654
6655 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
6656 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236657 MockWrite(
6658 "GET /x/y/a/b HTTP/1.1\r\n"
6659 "Host: www.example.org\r\n"
6660 "Connection: keep-alive\r\n"
6661 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236662 };
6663
6664 // Sever accepts the authorization.
6665 MockRead data_reads2[] = {
6666 MockRead("HTTP/1.0 200 OK\r\n"),
6667 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066668 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236669 };
6670
[email protected]31a2bfe2010-02-09 08:03:396671 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6672 data_writes1, arraysize(data_writes1));
6673 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6674 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076675 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6676 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236677
[email protected]49639fa2011-12-20 23:22:416678 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236679
[email protected]49639fa2011-12-20 23:22:416680 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426681 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236682
6683 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426684 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236685
[email protected]1c773ea12009-04-28 19:58:426686 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506687 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046688 ASSERT_TRUE(response->auth_challenge.get());
6689 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:236690 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:046691 response->auth_challenge->challenger.ToString());
6692 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:196693 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:236694
[email protected]49639fa2011-12-20 23:22:416695 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236696
[email protected]49639fa2011-12-20 23:22:416697 rv = trans->RestartWithAuth(
6698 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426699 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236700
6701 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426702 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236703
6704 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506705 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236706 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6707 EXPECT_EQ(100, response->headers->GetContentLength());
6708 }
6709
6710 // ------------------------------------------------------------------------
6711
6712 // Transaction 3: Resend a request in MyRealm's protection space --
6713 // succeed with preemptive authorization.
6714 {
[email protected]1c773ea12009-04-28 19:58:426715 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236716 request.method = "GET";
bncce36dca22015-04-21 22:11:236717 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:236718 request.load_flags = 0;
6719
[email protected]262eec82013-03-19 21:01:366720 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506721 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276722
[email protected]f9ee6b52008-11-08 06:46:236723 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236724 MockWrite(
6725 "GET /x/y/z2 HTTP/1.1\r\n"
6726 "Host: www.example.org\r\n"
6727 "Connection: keep-alive\r\n"
6728 // The authorization for MyRealm1 gets sent preemptively
6729 // (since the url is in the same protection space)
6730 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236731 };
6732
6733 // Sever accepts the preemptive authorization
6734 MockRead data_reads1[] = {
6735 MockRead("HTTP/1.0 200 OK\r\n"),
6736 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066737 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236738 };
6739
[email protected]31a2bfe2010-02-09 08:03:396740 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6741 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076742 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:236743
[email protected]49639fa2011-12-20 23:22:416744 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236745
[email protected]49639fa2011-12-20 23:22:416746 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426747 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236748
6749 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426750 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236751
[email protected]1c773ea12009-04-28 19:58:426752 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506753 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236754
6755 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6756 EXPECT_EQ(100, response->headers->GetContentLength());
6757 }
6758
6759 // ------------------------------------------------------------------------
6760
6761 // Transaction 4: request another URL in MyRealm (however the
6762 // url is not known to belong to the protection space, so no pre-auth).
6763 {
[email protected]1c773ea12009-04-28 19:58:426764 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236765 request.method = "GET";
bncce36dca22015-04-21 22:11:236766 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:236767 request.load_flags = 0;
6768
[email protected]262eec82013-03-19 21:01:366769 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276771
[email protected]f9ee6b52008-11-08 06:46:236772 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236773 MockWrite(
6774 "GET /x/1 HTTP/1.1\r\n"
6775 "Host: www.example.org\r\n"
6776 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236777 };
6778
6779 MockRead data_reads1[] = {
6780 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6781 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6782 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066783 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236784 };
6785
6786 // Resend with authorization from MyRealm's cache.
6787 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236788 MockWrite(
6789 "GET /x/1 HTTP/1.1\r\n"
6790 "Host: www.example.org\r\n"
6791 "Connection: keep-alive\r\n"
6792 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236793 };
6794
6795 // Sever accepts the authorization.
6796 MockRead data_reads2[] = {
6797 MockRead("HTTP/1.0 200 OK\r\n"),
6798 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066799 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236800 };
6801
[email protected]31a2bfe2010-02-09 08:03:396802 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6803 data_writes1, arraysize(data_writes1));
6804 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6805 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076806 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6807 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236808
[email protected]49639fa2011-12-20 23:22:416809 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236810
[email protected]49639fa2011-12-20 23:22:416811 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426812 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236813
6814 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426815 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236816
[email protected]0757e7702009-03-27 04:00:226817 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416818 TestCompletionCallback callback2;
6819 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426820 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226821 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426822 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226823 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6824
[email protected]1c773ea12009-04-28 19:58:426825 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506826 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236827 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6828 EXPECT_EQ(100, response->headers->GetContentLength());
6829 }
6830
6831 // ------------------------------------------------------------------------
6832
6833 // Transaction 5: request a URL in MyRealm, but the server rejects the
6834 // cached identity. Should invalidate and re-prompt.
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/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:236839 request.load_flags = 0;
6840
[email protected]262eec82013-03-19 21:01:366841 scoped_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 /p/q/t 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 from cache for MyRealm.
6859 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236860 MockWrite(
6861 "GET /p/q/t 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 rejects the authorization.
6868 MockRead data_reads2[] = {
6869 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6870 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6871 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066872 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236873 };
6874
6875 // At this point we should prompt for new credentials for MyRealm.
6876 // Restart with username=foo3, password=foo4.
6877 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236878 MockWrite(
6879 "GET /p/q/t HTTP/1.1\r\n"
6880 "Host: www.example.org\r\n"
6881 "Connection: keep-alive\r\n"
6882 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236883 };
6884
6885 // Sever accepts the authorization.
6886 MockRead data_reads3[] = {
6887 MockRead("HTTP/1.0 200 OK\r\n"),
6888 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066889 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236890 };
6891
[email protected]31a2bfe2010-02-09 08:03:396892 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6893 data_writes1, arraysize(data_writes1));
6894 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6895 data_writes2, arraysize(data_writes2));
6896 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6897 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076898 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6899 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6900 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236901
[email protected]49639fa2011-12-20 23:22:416902 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236903
[email protected]49639fa2011-12-20 23:22:416904 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426905 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236906
6907 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426908 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236909
[email protected]0757e7702009-03-27 04:00:226910 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416911 TestCompletionCallback callback2;
6912 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426913 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226914 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426915 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226916 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6917
[email protected]1c773ea12009-04-28 19:58:426918 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506919 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046920 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236921
[email protected]49639fa2011-12-20 23:22:416922 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236923
[email protected]49639fa2011-12-20 23:22:416924 rv = trans->RestartWithAuth(
6925 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426926 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236927
[email protected]0757e7702009-03-27 04:00:226928 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426929 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236930
6931 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506932 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236933 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6934 EXPECT_EQ(100, response->headers->GetContentLength());
6935 }
6936}
[email protected]89ceba9a2009-03-21 03:46:066937
[email protected]3c32c5f2010-05-18 15:18:126938// Tests that nonce count increments when multiple auth attempts
6939// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026940TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446941 HttpAuthHandlerDigest::Factory* digest_factory =
6942 new HttpAuthHandlerDigest::Factory();
6943 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6944 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6945 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076946 session_deps_.http_auth_handler_factory.reset(digest_factory);
mmenkee65e7af2015-10-13 17:16:426947 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126948
6949 // Transaction 1: authenticate (foo, bar) on MyRealm1
6950 {
[email protected]3c32c5f2010-05-18 15:18:126951 HttpRequestInfo request;
6952 request.method = "GET";
bncce36dca22015-04-21 22:11:236953 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126954 request.load_flags = 0;
6955
[email protected]262eec82013-03-19 21:01:366956 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506957 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276958
[email protected]3c32c5f2010-05-18 15:18:126959 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236960 MockWrite(
6961 "GET /x/y/z HTTP/1.1\r\n"
6962 "Host: www.example.org\r\n"
6963 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126964 };
6965
6966 MockRead data_reads1[] = {
6967 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6968 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6969 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066970 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126971 };
6972
6973 // Resend with authorization (username=foo, password=bar)
6974 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236975 MockWrite(
6976 "GET /x/y/z HTTP/1.1\r\n"
6977 "Host: www.example.org\r\n"
6978 "Connection: keep-alive\r\n"
6979 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6980 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6981 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6982 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126983 };
6984
6985 // Sever accepts the authorization.
6986 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:086987 MockRead("HTTP/1.0 200 OK\r\n"),
6988 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126989 };
6990
6991 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6992 data_writes1, arraysize(data_writes1));
6993 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6994 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076995 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6996 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126997
[email protected]49639fa2011-12-20 23:22:416998 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126999
[email protected]49639fa2011-12-20 23:22:417000 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:127001 EXPECT_EQ(ERR_IO_PENDING, rv);
7002
7003 rv = callback1.WaitForResult();
7004 EXPECT_EQ(OK, rv);
7005
7006 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507007 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:047008 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127009
[email protected]49639fa2011-12-20 23:22:417010 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127011
[email protected]49639fa2011-12-20 23:22:417012 rv = trans->RestartWithAuth(
7013 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:127014 EXPECT_EQ(ERR_IO_PENDING, rv);
7015
7016 rv = callback2.WaitForResult();
7017 EXPECT_EQ(OK, rv);
7018
7019 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507020 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:127021 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7022 }
7023
7024 // ------------------------------------------------------------------------
7025
7026 // Transaction 2: Request another resource in digestive's protection space.
7027 // This will preemptively add an Authorization header which should have an
7028 // "nc" value of 2 (as compared to 1 in the first use.
7029 {
[email protected]3c32c5f2010-05-18 15:18:127030 HttpRequestInfo request;
7031 request.method = "GET";
7032 // Note that Transaction 1 was at /x/y/z, so this is in the same
7033 // protection space as digest.
bncce36dca22015-04-21 22:11:237034 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127035 request.load_flags = 0;
7036
[email protected]262eec82013-03-19 21:01:367037 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507038 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277039
[email protected]3c32c5f2010-05-18 15:18:127040 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237041 MockWrite(
7042 "GET /x/y/a/b HTTP/1.1\r\n"
7043 "Host: www.example.org\r\n"
7044 "Connection: keep-alive\r\n"
7045 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7046 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7047 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7048 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127049 };
7050
7051 // Sever accepts the authorization.
7052 MockRead data_reads1[] = {
7053 MockRead("HTTP/1.0 200 OK\r\n"),
7054 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067055 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127056 };
7057
7058 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7059 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077060 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127061
[email protected]49639fa2011-12-20 23:22:417062 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127063
[email protected]49639fa2011-12-20 23:22:417064 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:127065 EXPECT_EQ(ERR_IO_PENDING, rv);
7066
7067 rv = callback1.WaitForResult();
7068 EXPECT_EQ(OK, rv);
7069
7070 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507071 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:127072 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7073 }
7074}
7075
[email protected]89ceba9a2009-03-21 03:46:067076// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:027077TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067078 // Create a transaction (the dependencies aren't important).
mmenkee65e7af2015-10-13 17:16:427079 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:407080 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:417081 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:067082
7083 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:067084 trans->read_buf_ = new IOBuffer(15);
7085 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:207086 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067087
7088 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:147089 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:577090 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087091 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577092 response->response_time = base::Time::Now();
7093 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067094
7095 { // Setup state for response_.vary_data
7096 HttpRequestInfo request;
7097 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7098 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277099 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437100 request.extra_headers.SetHeader("Foo", "1");
7101 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507102 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067103 }
7104
7105 // Cause the above state to be reset.
7106 trans->ResetStateForRestart();
7107
7108 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:077109 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:067110 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:207111 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:577112 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7113 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:047114 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087115 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577116 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067117}
7118
[email protected]bacff652009-03-31 17:50:337119// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:027120TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337121 HttpRequestInfo request;
7122 request.method = "GET";
bncce36dca22015-04-21 22:11:237123 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337124 request.load_flags = 0;
7125
mmenkee65e7af2015-10-13 17:16:427126 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277127 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277129
[email protected]bacff652009-03-31 17:50:337130 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237131 MockWrite(
7132 "GET / HTTP/1.1\r\n"
7133 "Host: www.example.org\r\n"
7134 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337135 };
7136
7137 MockRead data_reads[] = {
7138 MockRead("HTTP/1.0 200 OK\r\n"),
7139 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7140 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067141 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337142 };
7143
[email protected]5ecc992a42009-11-11 01:41:597144 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397145 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7146 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067147 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7148 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337149
[email protected]bb88e1d32013-05-03 23:11:077150 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7151 session_deps_.socket_factory->AddSocketDataProvider(&data);
7152 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7153 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337154
[email protected]49639fa2011-12-20 23:22:417155 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337156
[email protected]49639fa2011-12-20 23:22:417157 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337158 EXPECT_EQ(ERR_IO_PENDING, rv);
7159
7160 rv = callback.WaitForResult();
7161 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7162
[email protected]49639fa2011-12-20 23:22:417163 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337164 EXPECT_EQ(ERR_IO_PENDING, rv);
7165
7166 rv = callback.WaitForResult();
7167 EXPECT_EQ(OK, rv);
7168
7169 const HttpResponseInfo* response = trans->GetResponseInfo();
7170
[email protected]fe2255a2011-09-20 19:37:507171 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:337172 EXPECT_EQ(100, response->headers->GetContentLength());
7173}
7174
7175// Test HTTPS connections to a site with a bad certificate, going through a
7176// proxy
[email protected]23e482282013-06-14 16:08:027177TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037178 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337179
7180 HttpRequestInfo request;
7181 request.method = "GET";
bncce36dca22015-04-21 22:11:237182 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337183 request.load_flags = 0;
7184
7185 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177186 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7187 "Host: www.example.org:443\r\n"
7188 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337189 };
7190
7191 MockRead proxy_reads[] = {
7192 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067193 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337194 };
7195
7196 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177197 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7198 "Host: www.example.org:443\r\n"
7199 "Proxy-Connection: keep-alive\r\n\r\n"),
7200 MockWrite("GET / HTTP/1.1\r\n"
7201 "Host: www.example.org\r\n"
7202 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337203 };
7204
7205 MockRead data_reads[] = {
7206 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7207 MockRead("HTTP/1.0 200 OK\r\n"),
7208 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7209 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067210 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337211 };
7212
[email protected]31a2bfe2010-02-09 08:03:397213 StaticSocketDataProvider ssl_bad_certificate(
7214 proxy_reads, arraysize(proxy_reads),
7215 proxy_writes, arraysize(proxy_writes));
7216 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7217 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067218 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7219 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337220
[email protected]bb88e1d32013-05-03 23:11:077221 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7222 session_deps_.socket_factory->AddSocketDataProvider(&data);
7223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337225
[email protected]49639fa2011-12-20 23:22:417226 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337227
7228 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077229 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337230
mmenkee65e7af2015-10-13 17:16:427231 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:407232 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417233 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:337234
[email protected]49639fa2011-12-20 23:22:417235 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337236 EXPECT_EQ(ERR_IO_PENDING, rv);
7237
7238 rv = callback.WaitForResult();
7239 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7240
[email protected]49639fa2011-12-20 23:22:417241 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337242 EXPECT_EQ(ERR_IO_PENDING, rv);
7243
7244 rv = callback.WaitForResult();
7245 EXPECT_EQ(OK, rv);
7246
7247 const HttpResponseInfo* response = trans->GetResponseInfo();
7248
[email protected]fe2255a2011-09-20 19:37:507249 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:337250 EXPECT_EQ(100, response->headers->GetContentLength());
7251 }
7252}
7253
[email protected]2df19bb2010-08-25 20:13:467254
7255// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:027256TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037257 session_deps_.proxy_service =
7258 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517259 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077260 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467261
7262 HttpRequestInfo request;
7263 request.method = "GET";
bncce36dca22015-04-21 22:11:237264 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467265 request.load_flags = 0;
7266
7267 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177268 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7269 "Host: www.example.org:443\r\n"
7270 "Proxy-Connection: keep-alive\r\n\r\n"),
7271 MockWrite("GET / HTTP/1.1\r\n"
7272 "Host: www.example.org\r\n"
7273 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467274 };
7275
7276 MockRead data_reads[] = {
7277 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7278 MockRead("HTTP/1.1 200 OK\r\n"),
7279 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7280 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067281 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467282 };
7283
7284 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7285 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067286 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7287 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467288
[email protected]bb88e1d32013-05-03 23:11:077289 session_deps_.socket_factory->AddSocketDataProvider(&data);
7290 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7291 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467292
[email protected]49639fa2011-12-20 23:22:417293 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467294
mmenkee65e7af2015-10-13 17:16:427295 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467296 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417297 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467298
[email protected]49639fa2011-12-20 23:22:417299 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467300 EXPECT_EQ(ERR_IO_PENDING, rv);
7301
7302 rv = callback.WaitForResult();
7303 EXPECT_EQ(OK, rv);
7304 const HttpResponseInfo* response = trans->GetResponseInfo();
7305
[email protected]fe2255a2011-09-20 19:37:507306 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467307
7308 EXPECT_TRUE(response->headers->IsKeepAlive());
7309 EXPECT_EQ(200, response->headers->response_code());
7310 EXPECT_EQ(100, response->headers->GetContentLength());
7311 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207312
7313 LoadTimingInfo load_timing_info;
7314 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7315 TestLoadTimingNotReusedWithPac(load_timing_info,
7316 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467317}
7318
[email protected]511f6f52010-12-17 03:58:297319// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027320TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037321 session_deps_.proxy_service =
7322 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517323 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077324 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297325
7326 HttpRequestInfo request;
7327 request.method = "GET";
bncce36dca22015-04-21 22:11:237328 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297329 request.load_flags = 0;
7330
7331 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177332 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7333 "Host: www.example.org:443\r\n"
7334 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297335 };
7336
7337 MockRead data_reads[] = {
7338 MockRead("HTTP/1.1 302 Redirect\r\n"),
7339 MockRead("Location: http://login.example.com/\r\n"),
7340 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067341 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297342 };
7343
7344 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7345 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067346 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297347
[email protected]bb88e1d32013-05-03 23:11:077348 session_deps_.socket_factory->AddSocketDataProvider(&data);
7349 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297350
[email protected]49639fa2011-12-20 23:22:417351 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297352
mmenkee65e7af2015-10-13 17:16:427353 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297354 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417355 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297356
[email protected]49639fa2011-12-20 23:22:417357 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297358 EXPECT_EQ(ERR_IO_PENDING, rv);
7359
7360 rv = callback.WaitForResult();
7361 EXPECT_EQ(OK, rv);
7362 const HttpResponseInfo* response = trans->GetResponseInfo();
7363
[email protected]fe2255a2011-09-20 19:37:507364 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:297365
7366 EXPECT_EQ(302, response->headers->response_code());
7367 std::string url;
7368 EXPECT_TRUE(response->headers->IsRedirect(&url));
7369 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207370
7371 // In the case of redirects from proxies, HttpNetworkTransaction returns
7372 // timing for the proxy connection instead of the connection to the host,
7373 // and no send / receive times.
7374 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7375 LoadTimingInfo load_timing_info;
7376 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7377
7378 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:297379 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207380
7381 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7382 EXPECT_LE(load_timing_info.proxy_resolve_start,
7383 load_timing_info.proxy_resolve_end);
7384 EXPECT_LE(load_timing_info.proxy_resolve_end,
7385 load_timing_info.connect_timing.connect_start);
7386 ExpectConnectTimingHasTimes(
7387 load_timing_info.connect_timing,
7388 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7389
7390 EXPECT_TRUE(load_timing_info.send_start.is_null());
7391 EXPECT_TRUE(load_timing_info.send_end.is_null());
7392 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297393}
7394
7395// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027396TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037397 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297398
7399 HttpRequestInfo request;
7400 request.method = "GET";
bncce36dca22015-04-21 22:11:237401 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297402 request.load_flags = 0;
7403
bncb03b1092016-04-06 11:19:557404 scoped_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237405 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncb03b1092016-04-06 11:19:557406 scoped_ptr<SpdySerializedFrame> goaway(
[email protected]c10b20852013-05-15 21:29:207407 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297408 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137409 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
7410 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297411 };
7412
7413 static const char* const kExtraHeaders[] = {
7414 "location",
7415 "http://login.example.com/",
7416 };
bncb03b1092016-04-06 11:19:557417 scoped_ptr<SpdySerializedFrame> resp(spdy_util_.ConstructSpdySynReplyError(
7418 "302 Redirect", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297419 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137420 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297421 };
7422
rch8e6c6c42015-05-01 14:05:137423 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7424 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067425 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387426 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297427
[email protected]bb88e1d32013-05-03 23:11:077428 session_deps_.socket_factory->AddSocketDataProvider(&data);
7429 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297430
[email protected]49639fa2011-12-20 23:22:417431 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297432
mmenkee65e7af2015-10-13 17:16:427433 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297434 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417435 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297436
[email protected]49639fa2011-12-20 23:22:417437 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297438 EXPECT_EQ(ERR_IO_PENDING, rv);
7439
7440 rv = callback.WaitForResult();
7441 EXPECT_EQ(OK, rv);
7442 const HttpResponseInfo* response = trans->GetResponseInfo();
7443
[email protected]fe2255a2011-09-20 19:37:507444 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:297445
7446 EXPECT_EQ(302, response->headers->response_code());
7447 std::string url;
7448 EXPECT_TRUE(response->headers->IsRedirect(&url));
7449 EXPECT_EQ("http://login.example.com/", url);
7450}
7451
[email protected]4eddbc732012-08-09 05:40:177452// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027453TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177454 ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037455 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297456
7457 HttpRequestInfo request;
7458 request.method = "GET";
bncce36dca22015-04-21 22:11:237459 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297460 request.load_flags = 0;
7461
7462 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177463 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7464 "Host: www.example.org:443\r\n"
7465 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297466 };
7467
7468 MockRead data_reads[] = {
7469 MockRead("HTTP/1.1 404 Not Found\r\n"),
7470 MockRead("Content-Length: 23\r\n\r\n"),
7471 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067472 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297473 };
7474
7475 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7476 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067477 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297478
[email protected]bb88e1d32013-05-03 23:11:077479 session_deps_.socket_factory->AddSocketDataProvider(&data);
7480 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297481
[email protected]49639fa2011-12-20 23:22:417482 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297483
mmenkee65e7af2015-10-13 17:16:427484 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297485 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417486 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297487
[email protected]49639fa2011-12-20 23:22:417488 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297489 EXPECT_EQ(ERR_IO_PENDING, rv);
7490
7491 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177492 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297493
[email protected]4eddbc732012-08-09 05:40:177494 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297495}
7496
[email protected]4eddbc732012-08-09 05:40:177497// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027498TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177499 ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037500 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297501
7502 HttpRequestInfo request;
7503 request.method = "GET";
bncce36dca22015-04-21 22:11:237504 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297505 request.load_flags = 0;
7506
bncb03b1092016-04-06 11:19:557507 scoped_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237508 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncb03b1092016-04-06 11:19:557509 scoped_ptr<SpdySerializedFrame> rst(
[email protected]c10b20852013-05-15 21:29:207510 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297511 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137512 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:297513 };
7514
7515 static const char* const kExtraHeaders[] = {
7516 "location",
7517 "http://login.example.com/",
7518 };
bncb03b1092016-04-06 11:19:557519 scoped_ptr<SpdySerializedFrame> resp(spdy_util_.ConstructSpdySynReplyError(
7520 "404 Not Found", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
7521 scoped_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame(
7522 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297523 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137524 CreateMockRead(*resp.get(), 1),
7525 CreateMockRead(*body.get(), 2),
7526 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297527 };
7528
rch8e6c6c42015-05-01 14:05:137529 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7530 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067531 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387532 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297533
[email protected]bb88e1d32013-05-03 23:11:077534 session_deps_.socket_factory->AddSocketDataProvider(&data);
7535 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297536
[email protected]49639fa2011-12-20 23:22:417537 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297538
mmenkee65e7af2015-10-13 17:16:427539 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:297540 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417541 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297542
[email protected]49639fa2011-12-20 23:22:417543 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297544 EXPECT_EQ(ERR_IO_PENDING, rv);
7545
7546 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177547 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297548
[email protected]4eddbc732012-08-09 05:40:177549 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297550}
7551
[email protected]0c5fb722012-02-28 11:50:357552// Test the request-challenge-retry sequence for basic auth, through
7553// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:027554TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:357555 HttpRequestInfo request;
7556 request.method = "GET";
bncce36dca22015-04-21 22:11:237557 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:357558 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:297559 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:357560
7561 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037562 session_deps_.proxy_service =
7563 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517564 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077565 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:427566 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:357567
7568 // Since we have proxy, should try to establish tunnel.
bncb03b1092016-04-06 11:19:557569 scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237570 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
bncb03b1092016-04-06 11:19:557571 scoped_ptr<SpdySerializedFrame> rst(
[email protected]c10b20852013-05-15 21:29:207572 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
rdsmithebb50aa2015-11-12 03:44:387573 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:357574
7575 // After calling trans->RestartWithAuth(), this is the request we should
7576 // be issuing -- the final header line contains the credentials.
7577 const char* const kAuthCredentials[] = {
7578 "proxy-authorization", "Basic Zm9vOmJhcg==",
7579 };
bncb03b1092016-04-06 11:19:557580 scoped_ptr<SpdySerializedFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:347581 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:237582 HostPortPair("www.example.org", 443)));
7583 // fetch https://www.example.org/ via HTTP
7584 const char get[] =
7585 "GET / HTTP/1.1\r\n"
7586 "Host: www.example.org\r\n"
7587 "Connection: keep-alive\r\n\r\n";
bncb03b1092016-04-06 11:19:557588 scoped_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:027589 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:357590
7591 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137592 CreateMockWrite(*req, 0, ASYNC),
7593 CreateMockWrite(*rst, 2, ASYNC),
7594 CreateMockWrite(*connect2, 3),
7595 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:357596 };
7597
7598 // The proxy responds to the connect with a 407, using a persistent
7599 // connection.
thestig9d3bb0c2015-01-24 00:49:517600 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:357601 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:357602 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
7603 };
bncb03b1092016-04-06 11:19:557604 scoped_ptr<SpdySerializedFrame> conn_auth_resp(
7605 spdy_util_.ConstructSpdySynReplyError(kAuthStatus, kAuthChallenge,
7606 arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:357607
bncb03b1092016-04-06 11:19:557608 scoped_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:027609 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:357610 const char resp[] = "HTTP/1.1 200 OK\r\n"
7611 "Content-Length: 5\r\n\r\n";
7612
bncb03b1092016-04-06 11:19:557613 scoped_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:027614 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
bncb03b1092016-04-06 11:19:557615 scoped_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:027616 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:357617 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137618 CreateMockRead(*conn_auth_resp, 1, ASYNC),
7619 CreateMockRead(*conn_resp, 4, ASYNC),
7620 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
7621 CreateMockRead(*wrapped_body, 7, ASYNC),
7622 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:357623 };
7624
rch8e6c6c42015-05-01 14:05:137625 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7626 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077627 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:357628 // Negotiate SPDY to the proxy
7629 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387630 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077631 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:357632 // Vanilla SSL to the server
7633 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077634 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:357635
7636 TestCompletionCallback callback1;
7637
[email protected]262eec82013-03-19 21:01:367638 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507639 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:357640
7641 int rv = trans->Start(&request, callback1.callback(), log.bound());
7642 EXPECT_EQ(ERR_IO_PENDING, rv);
7643
7644 rv = callback1.WaitForResult();
7645 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:467646 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:357647 log.GetEntries(&entries);
7648 size_t pos = ExpectLogContainsSomewhere(
7649 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
7650 NetLog::PHASE_NONE);
7651 ExpectLogContainsSomewhere(
7652 entries, pos,
7653 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
7654 NetLog::PHASE_NONE);
7655
7656 const HttpResponseInfo* response = trans->GetResponseInfo();
7657 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:507658 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:357659 EXPECT_EQ(407, response->headers->response_code());
7660 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7661 EXPECT_TRUE(response->auth_challenge.get() != NULL);
7662 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
7663
7664 TestCompletionCallback callback2;
7665
7666 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
7667 callback2.callback());
7668 EXPECT_EQ(ERR_IO_PENDING, rv);
7669
7670 rv = callback2.WaitForResult();
7671 EXPECT_EQ(OK, rv);
7672
7673 response = trans->GetResponseInfo();
7674 ASSERT_TRUE(response != NULL);
7675
7676 EXPECT_TRUE(response->headers->IsKeepAlive());
7677 EXPECT_EQ(200, response->headers->response_code());
7678 EXPECT_EQ(5, response->headers->GetContentLength());
7679 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7680
7681 // The password prompt info should not be set.
7682 EXPECT_TRUE(response->auth_challenge.get() == NULL);
7683
[email protected]029c83b62013-01-24 05:28:207684 LoadTimingInfo load_timing_info;
7685 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7686 TestLoadTimingNotReusedWithPac(load_timing_info,
7687 CONNECT_TIMING_HAS_SSL_TIMES);
7688
[email protected]0c5fb722012-02-28 11:50:357689 trans.reset();
7690 session->CloseAllConnections();
7691}
7692
[email protected]7c6f7ba2012-04-03 04:09:297693// Test that an explicitly trusted SPDY proxy can push a resource from an
7694// origin that is different from that of its associated resource.
tbansal28e68f82016-02-04 02:56:157695TEST_P(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
7696 // Configure the proxy delegate to allow cross-origin SPDY pushes.
7697 scoped_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
7698 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
7699 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:297700 HttpRequestInfo request;
7701 HttpRequestInfo push_request;
7702
[email protected]7c6f7ba2012-04-03 04:09:297703 request.method = "GET";
bncce36dca22015-04-21 22:11:237704 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:297705 push_request.method = "GET";
7706 push_request.url = GURL("http://www.another-origin.com/foo.dat");
7707
tbansal28e68f82016-02-04 02:56:157708 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:037709 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:157710 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:517711 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077712 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507713
tbansal28e68f82016-02-04 02:56:157714 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:507715
mmenkee65e7af2015-10-13 17:16:427716 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:297717
bncb03b1092016-04-06 11:19:557718 scoped_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:497719 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:297720
7721 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137722 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:297723 };
7724
bncb03b1092016-04-06 11:19:557725 scoped_ptr<SpdySerializedFrame> stream1_reply(
7726 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:297727
bncb03b1092016-04-06 11:19:557728 scoped_ptr<SpdySerializedFrame> stream1_body(
7729 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:297730
bncb03b1092016-04-06 11:19:557731 scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
7732 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:437733 const char kPushedData[] = "pushed";
bncb03b1092016-04-06 11:19:557734 scoped_ptr<SpdySerializedFrame> stream2_body(
7735 spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
7736 true));
[email protected]7c6f7ba2012-04-03 04:09:297737
7738 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137739 CreateMockRead(*stream1_reply, 1, ASYNC),
7740 CreateMockRead(*stream2_syn, 2, ASYNC),
7741 CreateMockRead(*stream1_body, 3, ASYNC),
7742 CreateMockRead(*stream2_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:597743 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:297744 };
7745
rch8e6c6c42015-05-01 14:05:137746 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7747 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077748 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:297749 // Negotiate SPDY to the proxy
7750 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387751 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077752 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:297753
[email protected]262eec82013-03-19 21:01:367754 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507755 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:297756 TestCompletionCallback callback;
7757 int rv = trans->Start(&request, callback.callback(), log.bound());
7758 EXPECT_EQ(ERR_IO_PENDING, rv);
7759
7760 rv = callback.WaitForResult();
7761 EXPECT_EQ(OK, rv);
7762 const HttpResponseInfo* response = trans->GetResponseInfo();
7763
[email protected]262eec82013-03-19 21:01:367764 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:507765 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7766 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:297767 EXPECT_EQ(ERR_IO_PENDING, rv);
7768
7769 rv = callback.WaitForResult();
7770 EXPECT_EQ(OK, rv);
7771 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
7772
7773 ASSERT_TRUE(response != NULL);
7774 EXPECT_TRUE(response->headers->IsKeepAlive());
7775
7776 EXPECT_EQ(200, response->headers->response_code());
7777 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7778
7779 std::string response_data;
7780 rv = ReadTransaction(trans.get(), &response_data);
7781 EXPECT_EQ(OK, rv);
7782 EXPECT_EQ("hello!", response_data);
7783
[email protected]029c83b62013-01-24 05:28:207784 LoadTimingInfo load_timing_info;
7785 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7786 TestLoadTimingNotReusedWithPac(load_timing_info,
7787 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7788
[email protected]7c6f7ba2012-04-03 04:09:297789 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:507790 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:297791 EXPECT_EQ(200, push_response->headers->response_code());
7792
7793 rv = ReadTransaction(push_trans.get(), &response_data);
7794 EXPECT_EQ(OK, rv);
7795 EXPECT_EQ("pushed", response_data);
7796
[email protected]029c83b62013-01-24 05:28:207797 LoadTimingInfo push_load_timing_info;
7798 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
7799 TestLoadTimingReusedWithPac(push_load_timing_info);
7800 // The transactions should share a socket ID, despite being for different
7801 // origins.
7802 EXPECT_EQ(load_timing_info.socket_log_id,
7803 push_load_timing_info.socket_log_id);
7804
[email protected]7c6f7ba2012-04-03 04:09:297805 trans.reset();
7806 push_trans.reset();
7807 session->CloseAllConnections();
7808}
7809
[email protected]8c843192012-04-05 07:15:007810// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:027811TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:157812 // Configure the proxy delegate to allow cross-origin SPDY pushes.
7813 scoped_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
7814 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
7815 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:007816 HttpRequestInfo request;
7817
7818 request.method = "GET";
bncce36dca22015-04-21 22:11:237819 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:007820
tbansal28e68f82016-02-04 02:56:157821 session_deps_.proxy_service =
7822 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:517823 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077824 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507825
7826 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:157827 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:507828
mmenkee65e7af2015-10-13 17:16:427829 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:007830
bncb03b1092016-04-06 11:19:557831 scoped_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:497832 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:007833
bncb03b1092016-04-06 11:19:557834 scoped_ptr<SpdySerializedFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207835 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007836
7837 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137838 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007839 };
7840
bncb03b1092016-04-06 11:19:557841 scoped_ptr<SpdySerializedFrame> stream1_reply(
7842 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007843
bncb03b1092016-04-06 11:19:557844 scoped_ptr<SpdySerializedFrame> stream1_body(
7845 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007846
bncb03b1092016-04-06 11:19:557847 scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
7848 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:007849
7850 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137851 CreateMockRead(*stream1_reply, 1, ASYNC),
7852 CreateMockRead(*stream2_syn, 2, ASYNC),
7853 CreateMockRead(*stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:597854 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:007855 };
7856
rch8e6c6c42015-05-01 14:05:137857 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7858 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077859 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007860 // Negotiate SPDY to the proxy
7861 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387862 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077863 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007864
[email protected]262eec82013-03-19 21:01:367865 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507866 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007867 TestCompletionCallback callback;
7868 int rv = trans->Start(&request, callback.callback(), log.bound());
7869 EXPECT_EQ(ERR_IO_PENDING, rv);
7870
7871 rv = callback.WaitForResult();
7872 EXPECT_EQ(OK, rv);
7873 const HttpResponseInfo* response = trans->GetResponseInfo();
7874
7875 ASSERT_TRUE(response != NULL);
7876 EXPECT_TRUE(response->headers->IsKeepAlive());
7877
7878 EXPECT_EQ(200, response->headers->response_code());
7879 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7880
7881 std::string response_data;
7882 rv = ReadTransaction(trans.get(), &response_data);
7883 EXPECT_EQ(OK, rv);
7884 EXPECT_EQ("hello!", response_data);
7885
7886 trans.reset();
7887 session->CloseAllConnections();
7888}
7889
tbansal8ef1d3e2016-02-03 04:05:427890// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
7891// resources.
7892TEST_P(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:157893 // Configure the proxy delegate to allow cross-origin SPDY pushes.
7894 scoped_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
7895 proxy_delegate->set_trusted_spdy_proxy(
7896 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
7897
tbansal8ef1d3e2016-02-03 04:05:427898 HttpRequestInfo request;
7899
7900 request.method = "GET";
7901 request.url = GURL("http://www.example.org/");
7902
7903 // Configure against https proxy server "myproxy:70".
7904 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
7905 BoundTestNetLog log;
7906 session_deps_.net_log = log.bound().net_log();
7907
7908 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:157909 session_deps_.proxy_delegate.reset(proxy_delegate.release());
tbansal8ef1d3e2016-02-03 04:05:427910
7911 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7912
bncb03b1092016-04-06 11:19:557913 scoped_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:497914 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
tbansal8ef1d3e2016-02-03 04:05:427915
7916 MockWrite spdy_writes[] = {
7917 CreateMockWrite(*stream1_syn, 0, ASYNC),
7918 };
7919
bncb03b1092016-04-06 11:19:557920 scoped_ptr<SpdySerializedFrame> stream1_reply(
tbansal8ef1d3e2016-02-03 04:05:427921 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
7922
bncb03b1092016-04-06 11:19:557923 scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:497924 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
7925
bncb03b1092016-04-06 11:19:557926 scoped_ptr<SpdySerializedFrame> stream1_body(
tbansal8ef1d3e2016-02-03 04:05:427927 spdy_util_.ConstructSpdyBodyFrame(1, true));
7928
bncb03b1092016-04-06 11:19:557929 scoped_ptr<SpdySerializedFrame> stream2_reply(
tbansal8ef1d3e2016-02-03 04:05:427930 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
7931
bncb03b1092016-04-06 11:19:557932 scoped_ptr<SpdySerializedFrame> stream2_body(
tbansal8ef1d3e2016-02-03 04:05:427933 spdy_util_.ConstructSpdyBodyFrame(1, true));
7934
7935 MockRead spdy_reads[] = {
7936 CreateMockRead(*stream1_reply, 1, ASYNC),
7937 CreateMockRead(*stream2_syn, 2, ASYNC),
7938 CreateMockRead(*stream1_body, 3, ASYNC),
7939 CreateMockRead(*stream2_body, 4, ASYNC),
7940 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
7941 };
7942
7943 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7944 arraysize(spdy_writes));
7945 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
7946 // Negotiate SPDY to the proxy
7947 SSLSocketDataProvider proxy(ASYNC, OK);
7948 proxy.SetNextProto(GetProtocol());
7949 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
7950
7951 scoped_ptr<HttpTransaction> trans(
7952 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7953 TestCompletionCallback callback;
7954 int rv = trans->Start(&request, callback.callback(), log.bound());
7955 EXPECT_EQ(ERR_IO_PENDING, rv);
7956
7957 rv = callback.WaitForResult();
7958 EXPECT_EQ(OK, rv);
7959 const HttpResponseInfo* response = trans->GetResponseInfo();
7960
7961 ASSERT_TRUE(response != nullptr);
7962 EXPECT_TRUE(response->headers->IsKeepAlive());
7963
7964 EXPECT_EQ(200, response->headers->response_code());
7965 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7966
7967 std::string response_data;
7968 rv = ReadTransaction(trans.get(), &response_data);
7969 EXPECT_EQ(OK, rv);
7970 EXPECT_EQ("hello!", response_data);
7971
7972 trans.reset();
7973 session->CloseAllConnections();
7974}
7975
[email protected]2df19bb2010-08-25 20:13:467976// Test HTTPS connections to a site with a bad certificate, going through an
7977// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027978TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037979 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:467980
7981 HttpRequestInfo request;
7982 request.method = "GET";
bncce36dca22015-04-21 22:11:237983 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467984 request.load_flags = 0;
7985
7986 // Attempt to fetch the URL from a server with a bad cert
7987 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:177988 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7989 "Host: www.example.org:443\r\n"
7990 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467991 };
7992
7993 MockRead bad_cert_reads[] = {
7994 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067995 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467996 };
7997
7998 // Attempt to fetch the URL with a good cert
7999 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178000 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8001 "Host: www.example.org:443\r\n"
8002 "Proxy-Connection: keep-alive\r\n\r\n"),
8003 MockWrite("GET / HTTP/1.1\r\n"
8004 "Host: www.example.org\r\n"
8005 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468006 };
8007
8008 MockRead good_cert_reads[] = {
8009 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8010 MockRead("HTTP/1.0 200 OK\r\n"),
8011 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8012 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068013 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468014 };
8015
8016 StaticSocketDataProvider ssl_bad_certificate(
8017 bad_cert_reads, arraysize(bad_cert_reads),
8018 bad_cert_writes, arraysize(bad_cert_writes));
8019 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8020 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068021 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8022 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468023
8024 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078025 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8026 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8027 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468028
8029 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078030 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8031 session_deps_.socket_factory->AddSocketDataProvider(&data);
8032 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468033
[email protected]49639fa2011-12-20 23:22:418034 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468035
mmenkee65e7af2015-10-13 17:16:428036 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:468037 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418038 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:468039
[email protected]49639fa2011-12-20 23:22:418040 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:468041 EXPECT_EQ(ERR_IO_PENDING, rv);
8042
8043 rv = callback.WaitForResult();
8044 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
8045
[email protected]49639fa2011-12-20 23:22:418046 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:468047 EXPECT_EQ(ERR_IO_PENDING, rv);
8048
8049 rv = callback.WaitForResult();
8050 EXPECT_EQ(OK, rv);
8051
8052 const HttpResponseInfo* response = trans->GetResponseInfo();
8053
[email protected]fe2255a2011-09-20 19:37:508054 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:468055 EXPECT_EQ(100, response->headers->GetContentLength());
8056}
8057
[email protected]23e482282013-06-14 16:08:028058TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428059 HttpRequestInfo request;
8060 request.method = "GET";
bncce36dca22015-04-21 22:11:238061 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438062 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8063 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428064
mmenkee65e7af2015-10-13 17:16:428065 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278066 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418067 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278068
[email protected]1c773ea12009-04-28 19:58:428069 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238070 MockWrite(
8071 "GET / HTTP/1.1\r\n"
8072 "Host: www.example.org\r\n"
8073 "Connection: keep-alive\r\n"
8074 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428075 };
8076
8077 // Lastly, the server responds with the actual content.
8078 MockRead data_reads[] = {
8079 MockRead("HTTP/1.0 200 OK\r\n"),
8080 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8081 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068082 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428083 };
8084
[email protected]31a2bfe2010-02-09 08:03:398085 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8086 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078087 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428088
[email protected]49639fa2011-12-20 23:22:418089 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428090
[email protected]49639fa2011-12-20 23:22:418091 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428092 EXPECT_EQ(ERR_IO_PENDING, rv);
8093
8094 rv = callback.WaitForResult();
8095 EXPECT_EQ(OK, rv);
8096}
8097
[email protected]23e482282013-06-14 16:08:028098TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298099 HttpRequestInfo request;
8100 request.method = "GET";
bncce36dca22015-04-21 22:11:238101 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298102 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8103 "Chromium Ultra Awesome X Edition");
8104
rdsmith82957ad2015-09-16 19:42:038105 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
mmenkee65e7af2015-10-13 17:16:428106 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278107 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418108 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278109
[email protected]da81f132010-08-18 23:39:298110 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178111 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8112 "Host: www.example.org:443\r\n"
8113 "Proxy-Connection: keep-alive\r\n"
8114 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298115 };
8116 MockRead data_reads[] = {
8117 // Return an error, so the transaction stops here (this test isn't
8118 // interested in the rest).
8119 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8120 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8121 MockRead("Proxy-Connection: close\r\n\r\n"),
8122 };
8123
8124 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8125 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078126 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298127
[email protected]49639fa2011-12-20 23:22:418128 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298129
[email protected]49639fa2011-12-20 23:22:418130 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:298131 EXPECT_EQ(ERR_IO_PENDING, rv);
8132
8133 rv = callback.WaitForResult();
8134 EXPECT_EQ(OK, rv);
8135}
8136
[email protected]23e482282013-06-14 16:08:028137TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428138 HttpRequestInfo request;
8139 request.method = "GET";
bncce36dca22015-04-21 22:11:238140 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428141 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:168142 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8143 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428144
mmenkee65e7af2015-10-13 17:16:428145 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278146 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418147 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278148
[email protected]1c773ea12009-04-28 19:58:428149 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238150 MockWrite(
8151 "GET / HTTP/1.1\r\n"
8152 "Host: www.example.org\r\n"
8153 "Connection: keep-alive\r\n"
8154 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428155 };
8156
8157 // Lastly, the server responds with the actual content.
8158 MockRead data_reads[] = {
8159 MockRead("HTTP/1.0 200 OK\r\n"),
8160 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8161 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068162 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428163 };
8164
[email protected]31a2bfe2010-02-09 08:03:398165 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8166 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078167 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428168
[email protected]49639fa2011-12-20 23:22:418169 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428170
[email protected]49639fa2011-12-20 23:22:418171 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428172 EXPECT_EQ(ERR_IO_PENDING, rv);
8173
8174 rv = callback.WaitForResult();
8175 EXPECT_EQ(OK, rv);
8176}
8177
[email protected]23e482282013-06-14 16:08:028178TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428179 HttpRequestInfo request;
8180 request.method = "POST";
bncce36dca22015-04-21 22:11:238181 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428182
mmenkee65e7af2015-10-13 17:16:428183 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278184 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418185 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278186
[email protected]1c773ea12009-04-28 19:58:428187 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238188 MockWrite(
8189 "POST / HTTP/1.1\r\n"
8190 "Host: www.example.org\r\n"
8191 "Connection: keep-alive\r\n"
8192 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428193 };
8194
8195 // Lastly, the server responds with the actual content.
8196 MockRead data_reads[] = {
8197 MockRead("HTTP/1.0 200 OK\r\n"),
8198 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8199 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068200 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428201 };
8202
[email protected]31a2bfe2010-02-09 08:03:398203 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8204 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078205 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428206
[email protected]49639fa2011-12-20 23:22:418207 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428208
[email protected]49639fa2011-12-20 23:22:418209 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428210 EXPECT_EQ(ERR_IO_PENDING, rv);
8211
8212 rv = callback.WaitForResult();
8213 EXPECT_EQ(OK, rv);
8214}
8215
[email protected]23e482282013-06-14 16:08:028216TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428217 HttpRequestInfo request;
8218 request.method = "PUT";
bncce36dca22015-04-21 22:11:238219 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428220
mmenkee65e7af2015-10-13 17:16:428221 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278222 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418223 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278224
[email protected]1c773ea12009-04-28 19:58:428225 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238226 MockWrite(
8227 "PUT / HTTP/1.1\r\n"
8228 "Host: www.example.org\r\n"
8229 "Connection: keep-alive\r\n"
8230 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428231 };
8232
8233 // Lastly, the server responds with the actual content.
8234 MockRead data_reads[] = {
8235 MockRead("HTTP/1.0 200 OK\r\n"),
8236 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8237 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068238 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428239 };
8240
[email protected]31a2bfe2010-02-09 08:03:398241 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8242 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078243 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428244
[email protected]49639fa2011-12-20 23:22:418245 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428246
[email protected]49639fa2011-12-20 23:22:418247 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428248 EXPECT_EQ(ERR_IO_PENDING, rv);
8249
8250 rv = callback.WaitForResult();
8251 EXPECT_EQ(OK, rv);
8252}
8253
[email protected]23e482282013-06-14 16:08:028254TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428255 HttpRequestInfo request;
8256 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238257 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428258
mmenkee65e7af2015-10-13 17:16:428259 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278260 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418261 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278262
[email protected]1c773ea12009-04-28 19:58:428263 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138264 MockWrite("HEAD / HTTP/1.1\r\n"
8265 "Host: www.example.org\r\n"
8266 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428267 };
8268
8269 // Lastly, the server responds with the actual content.
8270 MockRead data_reads[] = {
8271 MockRead("HTTP/1.0 200 OK\r\n"),
8272 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8273 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068274 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428275 };
8276
[email protected]31a2bfe2010-02-09 08:03:398277 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8278 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078279 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428280
[email protected]49639fa2011-12-20 23:22:418281 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428282
[email protected]49639fa2011-12-20 23:22:418283 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428284 EXPECT_EQ(ERR_IO_PENDING, rv);
8285
8286 rv = callback.WaitForResult();
8287 EXPECT_EQ(OK, rv);
8288}
8289
[email protected]23e482282013-06-14 16:08:028290TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428291 HttpRequestInfo request;
8292 request.method = "GET";
bncce36dca22015-04-21 22:11:238293 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428294 request.load_flags = LOAD_BYPASS_CACHE;
8295
mmenkee65e7af2015-10-13 17:16:428296 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278297 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418298 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278299
[email protected]1c773ea12009-04-28 19:58:428300 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238301 MockWrite(
8302 "GET / HTTP/1.1\r\n"
8303 "Host: www.example.org\r\n"
8304 "Connection: keep-alive\r\n"
8305 "Pragma: no-cache\r\n"
8306 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428307 };
8308
8309 // Lastly, the server responds with the actual content.
8310 MockRead data_reads[] = {
8311 MockRead("HTTP/1.0 200 OK\r\n"),
8312 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8313 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068314 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428315 };
8316
[email protected]31a2bfe2010-02-09 08:03:398317 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8318 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078319 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428320
[email protected]49639fa2011-12-20 23:22:418321 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428322
[email protected]49639fa2011-12-20 23:22:418323 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428324 EXPECT_EQ(ERR_IO_PENDING, rv);
8325
8326 rv = callback.WaitForResult();
8327 EXPECT_EQ(OK, rv);
8328}
8329
[email protected]23e482282013-06-14 16:08:028330TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:428331 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428332 HttpRequestInfo request;
8333 request.method = "GET";
bncce36dca22015-04-21 22:11:238334 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428335 request.load_flags = LOAD_VALIDATE_CACHE;
8336
mmenkee65e7af2015-10-13 17:16:428337 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278338 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418339 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278340
[email protected]1c773ea12009-04-28 19:58:428341 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238342 MockWrite(
8343 "GET / HTTP/1.1\r\n"
8344 "Host: www.example.org\r\n"
8345 "Connection: keep-alive\r\n"
8346 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428347 };
8348
8349 // Lastly, the server responds with the actual content.
8350 MockRead data_reads[] = {
8351 MockRead("HTTP/1.0 200 OK\r\n"),
8352 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8353 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068354 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428355 };
8356
[email protected]31a2bfe2010-02-09 08:03:398357 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8358 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078359 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428360
[email protected]49639fa2011-12-20 23:22:418361 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428362
[email protected]49639fa2011-12-20 23:22:418363 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428364 EXPECT_EQ(ERR_IO_PENDING, rv);
8365
8366 rv = callback.WaitForResult();
8367 EXPECT_EQ(OK, rv);
8368}
8369
[email protected]23e482282013-06-14 16:08:028370TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428371 HttpRequestInfo request;
8372 request.method = "GET";
bncce36dca22015-04-21 22:11:238373 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438374 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428375
mmenkee65e7af2015-10-13 17:16:428376 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278377 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418378 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278379
[email protected]1c773ea12009-04-28 19:58:428380 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238381 MockWrite(
8382 "GET / HTTP/1.1\r\n"
8383 "Host: www.example.org\r\n"
8384 "Connection: keep-alive\r\n"
8385 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428386 };
8387
8388 // Lastly, the server responds with the actual content.
8389 MockRead data_reads[] = {
8390 MockRead("HTTP/1.0 200 OK\r\n"),
8391 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8392 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068393 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428394 };
8395
[email protected]31a2bfe2010-02-09 08:03:398396 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8397 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078398 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428399
[email protected]49639fa2011-12-20 23:22:418400 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428401
[email protected]49639fa2011-12-20 23:22:418402 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428403 EXPECT_EQ(ERR_IO_PENDING, rv);
8404
8405 rv = callback.WaitForResult();
8406 EXPECT_EQ(OK, rv);
8407}
8408
[email protected]23e482282013-06-14 16:08:028409TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478410 HttpRequestInfo request;
8411 request.method = "GET";
bncce36dca22015-04-21 22:11:238412 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438413 request.extra_headers.SetHeader("referer", "www.foo.com");
8414 request.extra_headers.SetHeader("hEllo", "Kitty");
8415 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478416
mmenkee65e7af2015-10-13 17:16:428417 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278418 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418419 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278420
[email protected]270c6412010-03-29 22:02:478421 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238422 MockWrite(
8423 "GET / HTTP/1.1\r\n"
8424 "Host: www.example.org\r\n"
8425 "Connection: keep-alive\r\n"
8426 "referer: www.foo.com\r\n"
8427 "hEllo: Kitty\r\n"
8428 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478429 };
8430
8431 // Lastly, the server responds with the actual content.
8432 MockRead data_reads[] = {
8433 MockRead("HTTP/1.0 200 OK\r\n"),
8434 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8435 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068436 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478437 };
8438
8439 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8440 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078441 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478442
[email protected]49639fa2011-12-20 23:22:418443 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478444
[email protected]49639fa2011-12-20 23:22:418445 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:478446 EXPECT_EQ(ERR_IO_PENDING, rv);
8447
8448 rv = callback.WaitForResult();
8449 EXPECT_EQ(OK, rv);
8450}
8451
[email protected]23e482282013-06-14 16:08:028452TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278453 HttpRequestInfo request;
8454 request.method = "GET";
bncce36dca22015-04-21 22:11:238455 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278456 request.load_flags = 0;
8457
rdsmith82957ad2015-09-16 19:42:038458 session_deps_.proxy_service =
8459 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518460 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078461 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028462
mmenkee65e7af2015-10-13 17:16:428463 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:028464 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418465 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028466
[email protected]3cd17242009-06-23 02:59:028467 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8468 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8469
8470 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238471 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8472 MockWrite(
8473 "GET / HTTP/1.1\r\n"
8474 "Host: www.example.org\r\n"
8475 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028476
8477 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068478 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028479 MockRead("HTTP/1.0 200 OK\r\n"),
8480 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8481 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068482 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028483 };
8484
[email protected]31a2bfe2010-02-09 08:03:398485 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8486 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078487 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028488
[email protected]49639fa2011-12-20 23:22:418489 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028490
[email protected]49639fa2011-12-20 23:22:418491 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028492 EXPECT_EQ(ERR_IO_PENDING, rv);
8493
8494 rv = callback.WaitForResult();
8495 EXPECT_EQ(OK, rv);
8496
8497 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508498 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:028499
[email protected]029c83b62013-01-24 05:28:208500 LoadTimingInfo load_timing_info;
8501 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8502 TestLoadTimingNotReusedWithPac(load_timing_info,
8503 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8504
[email protected]3cd17242009-06-23 02:59:028505 std::string response_text;
8506 rv = ReadTransaction(trans.get(), &response_text);
8507 EXPECT_EQ(OK, rv);
8508 EXPECT_EQ("Payload", response_text);
8509}
8510
[email protected]23e482282013-06-14 16:08:028511TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278512 HttpRequestInfo request;
8513 request.method = "GET";
bncce36dca22015-04-21 22:11:238514 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278515 request.load_flags = 0;
8516
rdsmith82957ad2015-09-16 19:42:038517 session_deps_.proxy_service =
8518 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518519 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078520 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028521
mmenkee65e7af2015-10-13 17:16:428522 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:028523 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418524 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028525
[email protected]3cd17242009-06-23 02:59:028526 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8527 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8528
8529 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238530 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8531 arraysize(write_buffer)),
8532 MockWrite(
8533 "GET / HTTP/1.1\r\n"
8534 "Host: www.example.org\r\n"
8535 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028536
8537 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018538 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8539 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358540 MockRead("HTTP/1.0 200 OK\r\n"),
8541 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8542 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068543 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358544 };
8545
[email protected]31a2bfe2010-02-09 08:03:398546 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8547 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078548 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358549
[email protected]8ddf8322012-02-23 18:08:068550 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078551 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358552
[email protected]49639fa2011-12-20 23:22:418553 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358554
[email protected]49639fa2011-12-20 23:22:418555 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358556 EXPECT_EQ(ERR_IO_PENDING, rv);
8557
8558 rv = callback.WaitForResult();
8559 EXPECT_EQ(OK, rv);
8560
[email protected]029c83b62013-01-24 05:28:208561 LoadTimingInfo load_timing_info;
8562 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8563 TestLoadTimingNotReusedWithPac(load_timing_info,
8564 CONNECT_TIMING_HAS_SSL_TIMES);
8565
[email protected]e0c27be2009-07-15 13:09:358566 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508567 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:358568
8569 std::string response_text;
8570 rv = ReadTransaction(trans.get(), &response_text);
8571 EXPECT_EQ(OK, rv);
8572 EXPECT_EQ("Payload", response_text);
8573}
8574
[email protected]23e482282013-06-14 16:08:028575TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:208576 HttpRequestInfo request;
8577 request.method = "GET";
bncce36dca22015-04-21 22:11:238578 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:208579 request.load_flags = 0;
8580
rdsmith82957ad2015-09-16 19:42:038581 session_deps_.proxy_service =
8582 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518583 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078584 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:208585
mmenkee65e7af2015-10-13 17:16:428586 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:208587 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418588 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:208589
8590 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8591 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8592
8593 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238594 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8595 MockWrite(
8596 "GET / HTTP/1.1\r\n"
8597 "Host: www.example.org\r\n"
8598 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:208599
8600 MockRead data_reads[] = {
8601 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
8602 MockRead("HTTP/1.0 200 OK\r\n"),
8603 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8604 MockRead("Payload"),
8605 MockRead(SYNCHRONOUS, OK)
8606 };
8607
8608 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8609 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078610 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:208611
8612 TestCompletionCallback callback;
8613
8614 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8615 EXPECT_EQ(ERR_IO_PENDING, rv);
8616
8617 rv = callback.WaitForResult();
8618 EXPECT_EQ(OK, rv);
8619
8620 const HttpResponseInfo* response = trans->GetResponseInfo();
8621 ASSERT_TRUE(response != NULL);
8622
8623 LoadTimingInfo load_timing_info;
8624 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8625 TestLoadTimingNotReused(load_timing_info,
8626 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8627
8628 std::string response_text;
8629 rv = ReadTransaction(trans.get(), &response_text);
8630 EXPECT_EQ(OK, rv);
8631 EXPECT_EQ("Payload", response_text);
8632}
8633
[email protected]23e482282013-06-14 16:08:028634TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278635 HttpRequestInfo request;
8636 request.method = "GET";
bncce36dca22015-04-21 22:11:238637 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278638 request.load_flags = 0;
8639
rdsmith82957ad2015-09-16 19:42:038640 session_deps_.proxy_service =
8641 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518642 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078643 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358644
mmenkee65e7af2015-10-13 17:16:428645 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:358646 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418647 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358648
[email protected]e0c27be2009-07-15 13:09:358649 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8650 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378651 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238652 0x05, // Version
8653 0x01, // Command (CONNECT)
8654 0x00, // Reserved.
8655 0x03, // Address type (DOMAINNAME).
8656 0x0F, // Length of domain (15)
8657 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8658 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:378659 };
[email protected]e0c27be2009-07-15 13:09:358660 const char kSOCKS5OkResponse[] =
8661 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
8662
8663 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238664 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8665 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
8666 MockWrite(
8667 "GET / HTTP/1.1\r\n"
8668 "Host: www.example.org\r\n"
8669 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358670
8671 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018672 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8673 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:358674 MockRead("HTTP/1.0 200 OK\r\n"),
8675 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8676 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068677 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358678 };
8679
[email protected]31a2bfe2010-02-09 08:03:398680 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8681 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078682 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358683
[email protected]49639fa2011-12-20 23:22:418684 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358685
[email protected]49639fa2011-12-20 23:22:418686 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358687 EXPECT_EQ(ERR_IO_PENDING, rv);
8688
8689 rv = callback.WaitForResult();
8690 EXPECT_EQ(OK, rv);
8691
8692 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508693 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:358694
[email protected]029c83b62013-01-24 05:28:208695 LoadTimingInfo load_timing_info;
8696 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8697 TestLoadTimingNotReusedWithPac(load_timing_info,
8698 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8699
[email protected]e0c27be2009-07-15 13:09:358700 std::string response_text;
8701 rv = ReadTransaction(trans.get(), &response_text);
8702 EXPECT_EQ(OK, rv);
8703 EXPECT_EQ("Payload", response_text);
8704}
8705
[email protected]23e482282013-06-14 16:08:028706TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278707 HttpRequestInfo request;
8708 request.method = "GET";
bncce36dca22015-04-21 22:11:238709 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278710 request.load_flags = 0;
8711
rdsmith82957ad2015-09-16 19:42:038712 session_deps_.proxy_service =
8713 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518714 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078715 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358716
mmenkee65e7af2015-10-13 17:16:428717 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:358718 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418719 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358720
[email protected]e0c27be2009-07-15 13:09:358721 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8722 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378723 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238724 0x05, // Version
8725 0x01, // Command (CONNECT)
8726 0x00, // Reserved.
8727 0x03, // Address type (DOMAINNAME).
8728 0x0F, // Length of domain (15)
8729 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8730 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:378731 };
8732
[email protected]e0c27be2009-07-15 13:09:358733 const char kSOCKS5OkResponse[] =
8734 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
8735
8736 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238737 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8738 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
8739 arraysize(kSOCKS5OkRequest)),
8740 MockWrite(
8741 "GET / HTTP/1.1\r\n"
8742 "Host: www.example.org\r\n"
8743 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358744
8745 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018746 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8747 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:028748 MockRead("HTTP/1.0 200 OK\r\n"),
8749 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8750 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068751 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028752 };
8753
[email protected]31a2bfe2010-02-09 08:03:398754 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8755 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078756 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028757
[email protected]8ddf8322012-02-23 18:08:068758 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:028760
[email protected]49639fa2011-12-20 23:22:418761 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028762
[email protected]49639fa2011-12-20 23:22:418763 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028764 EXPECT_EQ(ERR_IO_PENDING, rv);
8765
8766 rv = callback.WaitForResult();
8767 EXPECT_EQ(OK, rv);
8768
8769 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508770 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:028771
[email protected]029c83b62013-01-24 05:28:208772 LoadTimingInfo load_timing_info;
8773 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8774 TestLoadTimingNotReusedWithPac(load_timing_info,
8775 CONNECT_TIMING_HAS_SSL_TIMES);
8776
[email protected]3cd17242009-06-23 02:59:028777 std::string response_text;
8778 rv = ReadTransaction(trans.get(), &response_text);
8779 EXPECT_EQ(OK, rv);
8780 EXPECT_EQ("Payload", response_text);
8781}
8782
[email protected]448d4ca52012-03-04 04:12:238783namespace {
8784
[email protected]04e5be32009-06-26 20:00:318785// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:068786
8787struct GroupNameTest {
8788 std::string proxy_server;
8789 std::string url;
8790 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:188791 bool ssl;
[email protected]2d731a32010-04-29 01:04:068792};
8793
mmenkee65e7af2015-10-13 17:16:428794scoped_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:438795 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:078796 SpdySessionDependencies* session_deps_) {
mmenkee65e7af2015-10-13 17:16:428797 scoped_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:068798
[email protected]30d4c022013-07-18 22:58:168799 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538800 session->http_server_properties();
bnccacc0992015-03-20 20:22:228801 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:258802 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:128803 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:228804 http_server_properties->SetAlternativeService(
rchdc7b9052016-03-17 20:51:508805 HostPortPair("host.with.alternate", 80), alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:068806
8807 return session;
8808}
8809
mmenkee65e7af2015-10-13 17:16:428810int GroupNameTransactionHelper(const std::string& url,
8811 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:068812 HttpRequestInfo request;
8813 request.method = "GET";
8814 request.url = GURL(url);
8815 request.load_flags = 0;
8816
[email protected]262eec82013-03-19 21:01:368817 scoped_ptr<HttpTransaction> trans(
mmenkee65e7af2015-10-13 17:16:428818 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:278819
[email protected]49639fa2011-12-20 23:22:418820 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:068821
8822 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:418823 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:068824}
8825
[email protected]448d4ca52012-03-04 04:12:238826} // namespace
8827
[email protected]23e482282013-06-14 16:08:028828TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:068829 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238830 {
8831 "", // unused
8832 "http://www.example.org/direct",
8833 "www.example.org:80",
8834 false,
8835 },
8836 {
8837 "", // unused
8838 "http://[2001:1418:13:1::25]/direct",
8839 "[2001:1418:13:1::25]:80",
8840 false,
8841 },
[email protected]04e5be32009-06-26 20:00:318842
bncce36dca22015-04-21 22:11:238843 // SSL Tests
8844 {
8845 "", // unused
8846 "https://www.example.org/direct_ssl",
8847 "ssl/www.example.org:443",
8848 true,
8849 },
8850 {
8851 "", // unused
8852 "https://[2001:1418:13:1::25]/direct",
8853 "ssl/[2001:1418:13:1::25]:443",
8854 true,
8855 },
8856 {
8857 "", // unused
8858 "http://host.with.alternate/direct",
8859 "ssl/host.with.alternate:443",
8860 true,
8861 },
[email protected]2d731a32010-04-29 01:04:068862 };
[email protected]2ff8b312010-04-26 22:20:548863
bncf33fb31b2016-01-29 15:22:268864 session_deps_.parse_alternative_services = true;
8865 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d731a32010-04-29 01:04:068866
viettrungluue4a8b882014-10-16 06:17:388867 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038868 session_deps_.proxy_service =
8869 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:428870 scoped_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:388871 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068872
mmenkee65e7af2015-10-13 17:16:428873 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:288874 CaptureGroupNameTransportSocketPool* transport_conn_pool =
8875 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138876 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348877 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:448878 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8879 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028880 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
8881 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:488882 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:068883
8884 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428885 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188886 if (tests[i].ssl)
8887 EXPECT_EQ(tests[i].expected_group_name,
8888 ssl_conn_pool->last_group_name_received());
8889 else
8890 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:288891 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068892 }
[email protected]2d731a32010-04-29 01:04:068893}
8894
[email protected]23e482282013-06-14 16:08:028895TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:068896 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238897 {
8898 "http_proxy",
8899 "http://www.example.org/http_proxy_normal",
8900 "www.example.org:80",
8901 false,
8902 },
[email protected]2d731a32010-04-29 01:04:068903
bncce36dca22015-04-21 22:11:238904 // SSL Tests
8905 {
8906 "http_proxy",
8907 "https://www.example.org/http_connect_ssl",
8908 "ssl/www.example.org:443",
8909 true,
8910 },
[email protected]af3490e2010-10-16 21:02:298911
bncce36dca22015-04-21 22:11:238912 {
8913 "http_proxy",
8914 "http://host.with.alternate/direct",
8915 "ssl/host.with.alternate:443",
8916 true,
8917 },
[email protected]45499252013-01-23 17:12:568918
bncce36dca22015-04-21 22:11:238919 {
8920 "http_proxy",
8921 "ftp://ftp.google.com/http_proxy_normal",
8922 "ftp/ftp.google.com:21",
8923 false,
8924 },
[email protected]2d731a32010-04-29 01:04:068925 };
8926
bncf33fb31b2016-01-29 15:22:268927 session_deps_.parse_alternative_services = true;
8928 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d731a32010-04-29 01:04:068929
viettrungluue4a8b882014-10-16 06:17:388930 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:038931 session_deps_.proxy_service =
8932 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:428933 scoped_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:388934 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068935
mmenkee65e7af2015-10-13 17:16:428936 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:068937
[email protected]e60e47a2010-07-14 03:37:188938 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138939 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348940 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138941 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348942 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028943
[email protected]831e4a32013-11-14 02:14:448944 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8945 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028946 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8947 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:488948 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:068949
8950 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:428951 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:188952 if (tests[i].ssl)
8953 EXPECT_EQ(tests[i].expected_group_name,
8954 ssl_conn_pool->last_group_name_received());
8955 else
8956 EXPECT_EQ(tests[i].expected_group_name,
8957 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068958 }
[email protected]2d731a32010-04-29 01:04:068959}
8960
[email protected]23e482282013-06-14 16:08:028961TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068962 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238963 {
8964 "socks4://socks_proxy:1080",
8965 "http://www.example.org/socks4_direct",
8966 "socks4/www.example.org:80",
8967 false,
8968 },
8969 {
8970 "socks5://socks_proxy:1080",
8971 "http://www.example.org/socks5_direct",
8972 "socks5/www.example.org:80",
8973 false,
8974 },
[email protected]2d731a32010-04-29 01:04:068975
bncce36dca22015-04-21 22:11:238976 // SSL Tests
8977 {
8978 "socks4://socks_proxy:1080",
8979 "https://www.example.org/socks4_ssl",
8980 "socks4/ssl/www.example.org:443",
8981 true,
8982 },
8983 {
8984 "socks5://socks_proxy:1080",
8985 "https://www.example.org/socks5_ssl",
8986 "socks5/ssl/www.example.org:443",
8987 true,
8988 },
[email protected]af3490e2010-10-16 21:02:298989
bncce36dca22015-04-21 22:11:238990 {
8991 "socks4://socks_proxy:1080",
8992 "http://host.with.alternate/direct",
8993 "socks4/ssl/host.with.alternate:443",
8994 true,
8995 },
[email protected]04e5be32009-06-26 20:00:318996 };
8997
bncf33fb31b2016-01-29 15:22:268998 session_deps_.parse_alternative_services = true;
8999 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2ff8b312010-04-26 22:20:549000
viettrungluue4a8b882014-10-16 06:17:389001 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039002 session_deps_.proxy_service =
9003 ProxyService::CreateFixed(tests[i].proxy_server);
mmenkee65e7af2015-10-13 17:16:429004 scoped_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:389005 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:029006
mmenkee65e7af2015-10-13 17:16:429007 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319008
[email protected]e60e47a2010-07-14 03:37:189009 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139010 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349011 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139012 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349013 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029014
[email protected]831e4a32013-11-14 02:14:449015 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9016 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029017 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
9018 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489019 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319020
[email protected]262eec82013-03-19 21:01:369021 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509022 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:319023
[email protected]2d731a32010-04-29 01:04:069024 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429025 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189026 if (tests[i].ssl)
9027 EXPECT_EQ(tests[i].expected_group_name,
9028 ssl_conn_pool->last_group_name_received());
9029 else
9030 EXPECT_EQ(tests[i].expected_group_name,
9031 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319032 }
9033}
9034
[email protected]23e482282013-06-14 16:08:029035TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279036 HttpRequestInfo request;
9037 request.method = "GET";
bncce36dca22015-04-21 22:11:239038 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279039
rdsmith82957ad2015-09-16 19:42:039040 session_deps_.proxy_service =
9041 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329042
[email protected]69719062010-01-05 20:09:219043 // This simulates failure resolving all hostnames; that means we will fail
9044 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079045 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329046
mmenkee65e7af2015-10-13 17:16:429047 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:259048 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419049 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:259050
[email protected]49639fa2011-12-20 23:22:419051 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259052
[email protected]49639fa2011-12-20 23:22:419053 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:259054 EXPECT_EQ(ERR_IO_PENDING, rv);
9055
[email protected]9172a982009-06-06 00:30:259056 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:019057 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:259058}
9059
[email protected]685af592010-05-11 19:31:249060// Base test to make sure that when the load flags for a request specify to
9061// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029062void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079063 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279064 // Issue a request, asking to bypass the cache(s).
9065 HttpRequestInfo request;
9066 request.method = "GET";
9067 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:239068 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279069
[email protected]a2c2fb92009-07-18 07:31:049070 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:079071 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:329072
mmenkee65e7af2015-10-13 17:16:429073 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:079074 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419075 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:289076
bncce36dca22015-04-21 22:11:239077 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289078 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299079 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:079080 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239081 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
9082 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:479083 EXPECT_EQ(ERR_IO_PENDING, rv);
9084 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289085 EXPECT_EQ(OK, rv);
9086
9087 // Verify that it was added to host cache, by doing a subsequent async lookup
9088 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:079089 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239090 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
9091 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:329092 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:289093
bncce36dca22015-04-21 22:11:239094 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289095 // we can tell if the next lookup hit the cache, or the "network".
9096 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239097 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289098
9099 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9100 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069101 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399102 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079103 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289104
[email protected]3b9cca42009-06-16 01:08:289105 // Run the request.
[email protected]49639fa2011-12-20 23:22:419106 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:289107 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419108 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289109
9110 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239111 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289112 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
9113}
9114
[email protected]685af592010-05-11 19:31:249115// There are multiple load flags that should trigger the host cache bypass.
9116// Test each in isolation:
[email protected]23e482282013-06-14 16:08:029117TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249118 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9119}
9120
[email protected]23e482282013-06-14 16:08:029121TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249122 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9123}
9124
[email protected]23e482282013-06-14 16:08:029125TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249126 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9127}
9128
[email protected]0877e3d2009-10-17 22:29:579129// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:029130TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579131 HttpRequestInfo request;
9132 request.method = "GET";
9133 request.url = GURL("http://www.foo.com/");
9134 request.load_flags = 0;
9135
9136 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069137 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579138 };
[email protected]31a2bfe2010-02-09 08:03:399139 StaticSocketDataProvider data(NULL, 0,
9140 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079141 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenkee65e7af2015-10-13 17:16:429142 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579143
[email protected]49639fa2011-12-20 23:22:419144 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579145
9146 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419147 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579148
[email protected]49639fa2011-12-20 23:22:419149 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579150 EXPECT_EQ(ERR_IO_PENDING, rv);
9151
9152 rv = callback.WaitForResult();
9153 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:599154
9155 IPEndPoint endpoint;
9156 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
9157 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579158}
9159
zmo9528c9f42015-08-04 22:12:089160// Check that a connection closed after the start of the headers finishes ok.
9161TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579162 HttpRequestInfo request;
9163 request.method = "GET";
9164 request.url = GURL("http://www.foo.com/");
9165 request.load_flags = 0;
9166
9167 MockRead data_reads[] = {
9168 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069169 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579170 };
9171
[email protected]31a2bfe2010-02-09 08:03:399172 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079173 session_deps_.socket_factory->AddSocketDataProvider(&data);
mmenkee65e7af2015-10-13 17:16:429174 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579175
[email protected]49639fa2011-12-20 23:22:419176 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579177
9178 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419179 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579180
[email protected]49639fa2011-12-20 23:22:419181 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579182 EXPECT_EQ(ERR_IO_PENDING, rv);
9183
9184 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:089185 EXPECT_EQ(OK, rv);
9186
9187 const HttpResponseInfo* response = trans->GetResponseInfo();
9188 ASSERT_TRUE(response != NULL);
9189
9190 EXPECT_TRUE(response->headers.get() != NULL);
9191 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9192
9193 std::string response_data;
9194 rv = ReadTransaction(trans.get(), &response_data);
9195 EXPECT_EQ(OK, rv);
9196 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599197
9198 IPEndPoint endpoint;
9199 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
9200 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579201}
9202
9203// Make sure that a dropped connection while draining the body for auth
9204// restart does the right thing.
[email protected]23e482282013-06-14 16:08:029205TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579206 HttpRequestInfo request;
9207 request.method = "GET";
bncce36dca22015-04-21 22:11:239208 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579209 request.load_flags = 0;
9210
9211 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239212 MockWrite(
9213 "GET / HTTP/1.1\r\n"
9214 "Host: www.example.org\r\n"
9215 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579216 };
9217
9218 MockRead data_reads1[] = {
9219 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9220 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9221 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9222 MockRead("Content-Length: 14\r\n\r\n"),
9223 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069224 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579225 };
9226
[email protected]31a2bfe2010-02-09 08:03:399227 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9228 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079229 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579230
9231 // After calling trans->RestartWithAuth(), this is the request we should
9232 // be issuing -- the final header line contains the credentials.
9233 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239234 MockWrite(
9235 "GET / HTTP/1.1\r\n"
9236 "Host: www.example.org\r\n"
9237 "Connection: keep-alive\r\n"
9238 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579239 };
9240
9241 // Lastly, the server responds with the actual content.
9242 MockRead data_reads2[] = {
9243 MockRead("HTTP/1.1 200 OK\r\n"),
9244 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9245 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069246 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579247 };
9248
[email protected]31a2bfe2010-02-09 08:03:399249 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9250 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079251 session_deps_.socket_factory->AddSocketDataProvider(&data2);
mmenkee65e7af2015-10-13 17:16:429252 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579253
[email protected]49639fa2011-12-20 23:22:419254 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579255
[email protected]262eec82013-03-19 21:01:369256 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509257 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509258
[email protected]49639fa2011-12-20 23:22:419259 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579260 EXPECT_EQ(ERR_IO_PENDING, rv);
9261
9262 rv = callback1.WaitForResult();
9263 EXPECT_EQ(OK, rv);
9264
9265 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509266 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049267 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579268
[email protected]49639fa2011-12-20 23:22:419269 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579270
[email protected]49639fa2011-12-20 23:22:419271 rv = trans->RestartWithAuth(
9272 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:579273 EXPECT_EQ(ERR_IO_PENDING, rv);
9274
9275 rv = callback2.WaitForResult();
9276 EXPECT_EQ(OK, rv);
9277
9278 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509279 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:579280 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9281 EXPECT_EQ(100, response->headers->GetContentLength());
9282}
9283
9284// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:029285TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039286 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579287
9288 HttpRequestInfo request;
9289 request.method = "GET";
bncce36dca22015-04-21 22:11:239290 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579291 request.load_flags = 0;
9292
9293 MockRead proxy_reads[] = {
9294 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069295 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579296 };
9297
[email protected]31a2bfe2010-02-09 08:03:399298 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069299 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579300
[email protected]bb88e1d32013-05-03 23:11:079301 session_deps_.socket_factory->AddSocketDataProvider(&data);
9302 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579303
[email protected]49639fa2011-12-20 23:22:419304 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579305
[email protected]bb88e1d32013-05-03 23:11:079306 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579307
mmenkee65e7af2015-10-13 17:16:429308 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579309 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419310 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579311
[email protected]49639fa2011-12-20 23:22:419312 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579313 EXPECT_EQ(ERR_IO_PENDING, rv);
9314
9315 rv = callback.WaitForResult();
9316 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
9317}
9318
[email protected]23e482282013-06-14 16:08:029319TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469320 HttpRequestInfo request;
9321 request.method = "GET";
bncce36dca22015-04-21 22:11:239322 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469323 request.load_flags = 0;
9324
mmenkee65e7af2015-10-13 17:16:429325 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:279326 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419327 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:279328
[email protected]e22e1362009-11-23 21:31:129329 MockRead data_reads[] = {
9330 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069331 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129332 };
[email protected]9492e4a2010-02-24 00:58:469333
9334 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079335 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469336
[email protected]49639fa2011-12-20 23:22:419337 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469338
[email protected]49639fa2011-12-20 23:22:419339 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:469340 EXPECT_EQ(ERR_IO_PENDING, rv);
9341
9342 EXPECT_EQ(OK, callback.WaitForResult());
9343
9344 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509345 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:469346
[email protected]90499482013-06-01 00:39:509347 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:469348 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9349
9350 std::string response_data;
9351 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:239352 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:129353}
9354
[email protected]23e482282013-06-14 16:08:029355TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159356 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529357 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149358 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219359 UploadFileElementReader::ScopedOverridingContentLengthForTests
9360 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339361
olli.raula6df48b2a2015-11-26 07:40:229362 std::vector<scoped_ptr<UploadElementReader>> element_readers;
9363 element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
avibf0746c2015-12-09 19:53:149364 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
9365 std::numeric_limits<uint64_t>::max(), base::Time())));
olli.raula6df48b2a2015-11-26 07:40:229366 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279367
9368 HttpRequestInfo request;
9369 request.method = "POST";
bncce36dca22015-04-21 22:11:239370 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279371 request.upload_data_stream = &upload_data_stream;
9372 request.load_flags = 0;
9373
mmenkee65e7af2015-10-13 17:16:429374 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:279375 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419376 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:339377
9378 MockRead data_reads[] = {
9379 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9380 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069381 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339382 };
[email protected]31a2bfe2010-02-09 08:03:399383 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079384 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339385
[email protected]49639fa2011-12-20 23:22:419386 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339387
[email protected]49639fa2011-12-20 23:22:419388 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:339389 EXPECT_EQ(ERR_IO_PENDING, rv);
9390
9391 rv = callback.WaitForResult();
9392 EXPECT_EQ(OK, rv);
9393
9394 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509395 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:339396
[email protected]90499482013-06-01 00:39:509397 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:339398 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9399
9400 std::string response_data;
9401 rv = ReadTransaction(trans.get(), &response_data);
9402 EXPECT_EQ(OK, rv);
9403 EXPECT_EQ("hello world", response_data);
9404
[email protected]dd3aa792013-07-16 19:10:239405 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339406}
9407
[email protected]23e482282013-06-14 16:08:029408TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159409 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529410 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369411 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309412 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369413 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119414 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369415
olli.raula6df48b2a2015-11-26 07:40:229416 std::vector<scoped_ptr<UploadElementReader>> element_readers;
avibf0746c2015-12-09 19:53:149417 element_readers.push_back(make_scoped_ptr(new UploadFileElementReader(
9418 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
9419 std::numeric_limits<uint64_t>::max(), base::Time())));
olli.raula6df48b2a2015-11-26 07:40:229420 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279421
9422 HttpRequestInfo request;
9423 request.method = "POST";
bncce36dca22015-04-21 22:11:239424 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279425 request.upload_data_stream = &upload_data_stream;
9426 request.load_flags = 0;
9427
[email protected]999dd8c2013-11-12 06:45:549428 // If we try to upload an unreadable file, the transaction should fail.
mmenkee65e7af2015-10-13 17:16:429429 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:279430 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419431 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:369432
[email protected]999dd8c2013-11-12 06:45:549433 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079434 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369435
[email protected]49639fa2011-12-20 23:22:419436 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369437
[email protected]49639fa2011-12-20 23:22:419438 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:369439 EXPECT_EQ(ERR_IO_PENDING, rv);
9440
9441 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:549442 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:369443
[email protected]dd3aa792013-07-16 19:10:239444 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369445}
9446
[email protected]02cad5d2013-10-02 08:14:039447TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
9448 class FakeUploadElementReader : public UploadElementReader {
9449 public:
9450 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209451 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039452
9453 const CompletionCallback& callback() const { return callback_; }
9454
9455 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209456 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039457 callback_ = callback;
9458 return ERR_IO_PENDING;
9459 }
avibf0746c2015-12-09 19:53:149460 uint64_t GetContentLength() const override { return 0; }
9461 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209462 int Read(IOBuffer* buf,
9463 int buf_length,
9464 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039465 return ERR_FAILED;
9466 }
9467
9468 private:
9469 CompletionCallback callback_;
9470 };
9471
9472 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
olli.raula6df48b2a2015-11-26 07:40:229473 std::vector<scoped_ptr<UploadElementReader>> element_readers;
9474 element_readers.push_back(make_scoped_ptr(fake_reader));
9475 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039476
9477 HttpRequestInfo request;
9478 request.method = "POST";
bncce36dca22015-04-21 22:11:239479 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039480 request.upload_data_stream = &upload_data_stream;
9481 request.load_flags = 0;
9482
mmenkee65e7af2015-10-13 17:16:429483 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:039484 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419485 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039486
9487 StaticSocketDataProvider data;
9488 session_deps_.socket_factory->AddSocketDataProvider(&data);
9489
9490 TestCompletionCallback callback;
9491 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9492 EXPECT_EQ(ERR_IO_PENDING, rv);
9493 base::MessageLoop::current()->RunUntilIdle();
9494
9495 // Transaction is pending on request body initialization.
9496 ASSERT_FALSE(fake_reader->callback().is_null());
9497
9498 // Return Init()'s result after the transaction gets destroyed.
9499 trans.reset();
9500 fake_reader->callback().Run(OK); // Should not crash.
9501}
9502
[email protected]aeefc9e82010-02-19 16:18:279503// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:029504TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279505 HttpRequestInfo request;
9506 request.method = "GET";
bncce36dca22015-04-21 22:11:239507 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279508 request.load_flags = 0;
9509
9510 // First transaction will request a resource and receive a Basic challenge
9511 // with realm="first_realm".
9512 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239513 MockWrite(
9514 "GET / HTTP/1.1\r\n"
9515 "Host: www.example.org\r\n"
9516 "Connection: keep-alive\r\n"
9517 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279518 };
9519 MockRead data_reads1[] = {
9520 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9521 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9522 "\r\n"),
9523 };
9524
9525 // After calling trans->RestartWithAuth(), provide an Authentication header
9526 // for first_realm. The server will reject and provide a challenge with
9527 // second_realm.
9528 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239529 MockWrite(
9530 "GET / HTTP/1.1\r\n"
9531 "Host: www.example.org\r\n"
9532 "Connection: keep-alive\r\n"
9533 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9534 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279535 };
9536 MockRead data_reads2[] = {
9537 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9538 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9539 "\r\n"),
9540 };
9541
9542 // This again fails, and goes back to first_realm. Make sure that the
9543 // entry is removed from cache.
9544 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239545 MockWrite(
9546 "GET / HTTP/1.1\r\n"
9547 "Host: www.example.org\r\n"
9548 "Connection: keep-alive\r\n"
9549 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9550 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279551 };
9552 MockRead data_reads3[] = {
9553 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9554 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9555 "\r\n"),
9556 };
9557
9558 // Try one last time (with the correct password) and get the resource.
9559 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239560 MockWrite(
9561 "GET / HTTP/1.1\r\n"
9562 "Host: www.example.org\r\n"
9563 "Connection: keep-alive\r\n"
9564 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9565 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279566 };
9567 MockRead data_reads4[] = {
9568 MockRead("HTTP/1.1 200 OK\r\n"
9569 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509570 "Content-Length: 5\r\n"
9571 "\r\n"
9572 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279573 };
9574
9575 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9576 data_writes1, arraysize(data_writes1));
9577 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9578 data_writes2, arraysize(data_writes2));
9579 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9580 data_writes3, arraysize(data_writes3));
9581 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9582 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079583 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9584 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9585 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9586 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279587
[email protected]49639fa2011-12-20 23:22:419588 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279589
mmenkee65e7af2015-10-13 17:16:429590 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:509591 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419592 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509593
[email protected]aeefc9e82010-02-19 16:18:279594 // Issue the first request with Authorize headers. There should be a
9595 // password prompt for first_realm waiting to be filled in after the
9596 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419597 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:279598 EXPECT_EQ(ERR_IO_PENDING, rv);
9599 rv = callback1.WaitForResult();
9600 EXPECT_EQ(OK, rv);
9601 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509602 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049603 const AuthChallengeInfo* challenge = response->auth_challenge.get();
9604 ASSERT_FALSE(challenge == NULL);
9605 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239606 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049607 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199608 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279609
9610 // Issue the second request with an incorrect password. There should be a
9611 // password prompt for second_realm waiting to be filled in after the
9612 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419613 TestCompletionCallback callback2;
9614 rv = trans->RestartWithAuth(
9615 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:279616 EXPECT_EQ(ERR_IO_PENDING, rv);
9617 rv = callback2.WaitForResult();
9618 EXPECT_EQ(OK, rv);
9619 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509620 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049621 challenge = response->auth_challenge.get();
9622 ASSERT_FALSE(challenge == NULL);
9623 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239624 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049625 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199626 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279627
9628 // Issue the third request with another incorrect password. There should be
9629 // a password prompt for first_realm waiting to be filled in. If the password
9630 // prompt is not present, it indicates that the HttpAuthCacheEntry for
9631 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:419632 TestCompletionCallback callback3;
9633 rv = trans->RestartWithAuth(
9634 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:279635 EXPECT_EQ(ERR_IO_PENDING, rv);
9636 rv = callback3.WaitForResult();
9637 EXPECT_EQ(OK, rv);
9638 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509639 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:049640 challenge = response->auth_challenge.get();
9641 ASSERT_FALSE(challenge == NULL);
9642 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:239643 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:049644 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199645 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279646
9647 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:419648 TestCompletionCallback callback4;
9649 rv = trans->RestartWithAuth(
9650 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:279651 EXPECT_EQ(ERR_IO_PENDING, rv);
9652 rv = callback4.WaitForResult();
9653 EXPECT_EQ(OK, rv);
9654 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:509655 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:279656 EXPECT_TRUE(response->auth_challenge.get() == NULL);
9657}
9658
bncc958faa2015-07-31 18:14:529659TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:269660 session_deps_.parse_alternative_services = true;
9661 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:529662
9663 std::string alternative_service_http_header =
9664 GetAlternativeServiceHttpHeader();
9665
9666 MockRead data_reads[] = {
9667 MockRead("HTTP/1.1 200 OK\r\n"),
9668 MockRead(alternative_service_http_header.c_str()),
9669 MockRead("\r\n"),
9670 MockRead("hello world"),
9671 MockRead(SYNCHRONOUS, OK),
9672 };
9673
9674 HttpRequestInfo request;
9675 request.method = "GET";
9676 request.url = GURL("http://www.example.org/");
9677 request.load_flags = 0;
9678
9679 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9680
9681 session_deps_.socket_factory->AddSocketDataProvider(&data);
9682
9683 TestCompletionCallback callback;
9684
mmenkee65e7af2015-10-13 17:16:429685 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529686 scoped_ptr<HttpTransaction> trans(
9687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9688
9689 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9690 EXPECT_EQ(ERR_IO_PENDING, rv);
9691
9692 HostPortPair http_host_port_pair("www.example.org", 80);
9693 HttpServerProperties& http_server_properties =
9694 *session->http_server_properties();
9695 AlternativeServiceVector alternative_service_vector =
9696 http_server_properties.GetAlternativeServices(http_host_port_pair);
9697 EXPECT_TRUE(alternative_service_vector.empty());
9698
9699 EXPECT_EQ(OK, callback.WaitForResult());
9700
9701 const HttpResponseInfo* response = trans->GetResponseInfo();
9702 ASSERT_TRUE(response != NULL);
9703 ASSERT_TRUE(response->headers.get() != NULL);
9704 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9705 EXPECT_FALSE(response->was_fetched_via_spdy);
9706 EXPECT_FALSE(response->was_npn_negotiated);
9707
9708 std::string response_data;
9709 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9710 EXPECT_EQ("hello world", response_data);
9711
9712 alternative_service_vector =
9713 http_server_properties.GetAlternativeServices(http_host_port_pair);
9714 ASSERT_EQ(1u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:389715 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:529716 alternative_service_vector[0].protocol);
9717 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9718 EXPECT_EQ(443, alternative_service_vector[0].port);
9719}
9720
bnc4f575852015-10-14 18:35:089721TEST_P(HttpNetworkTransactionTest, ClearAlternativeServices) {
bncf33fb31b2016-01-29 15:22:269722 session_deps_.parse_alternative_services = true;
9723 session_deps_.enable_alternative_service_with_different_host = false;
bnc4f575852015-10-14 18:35:089724
9725 // Set an alternative service for origin.
9726 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9727 HttpServerProperties& http_server_properties =
9728 *session->http_server_properties();
9729 HostPortPair http_host_port_pair("www.example.org", 80);
9730 AlternativeService alternative_service(QUIC, "", 80);
9731 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
rchdc7b9052016-03-17 20:51:509732 http_server_properties.SetAlternativeService(http_host_port_pair,
9733 alternative_service, expiration);
bnc4f575852015-10-14 18:35:089734 AlternativeServiceVector alternative_service_vector =
9735 http_server_properties.GetAlternativeServices(http_host_port_pair);
9736 EXPECT_EQ(1u, alternative_service_vector.size());
9737
9738 // Send a clear header.
9739 MockRead data_reads[] = {
9740 MockRead("HTTP/1.1 200 OK\r\n"),
9741 MockRead("Alt-Svc: clear\r\n"),
9742 MockRead("\r\n"),
9743 MockRead("hello world"),
9744 MockRead(SYNCHRONOUS, OK),
9745 };
9746 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
9747 session_deps_.socket_factory->AddSocketDataProvider(&data);
9748
9749 HttpRequestInfo request;
9750 request.method = "GET";
9751 request.url = GURL("http://www.example.org/");
9752 request.load_flags = 0;
9753
9754 TestCompletionCallback callback;
9755
9756 scoped_ptr<HttpTransaction> trans(
9757 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9758
9759 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9760 EXPECT_EQ(OK, callback.GetResult(rv));
9761
9762 const HttpResponseInfo* response = trans->GetResponseInfo();
9763 ASSERT_TRUE(response != nullptr);
9764 ASSERT_TRUE(response->headers.get() != nullptr);
9765 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9766 EXPECT_FALSE(response->was_fetched_via_spdy);
9767 EXPECT_FALSE(response->was_npn_negotiated);
9768
9769 std::string response_data;
9770 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9771 EXPECT_EQ("hello world", response_data);
9772
9773 alternative_service_vector =
9774 http_server_properties.GetAlternativeServices(http_host_port_pair);
9775 EXPECT_TRUE(alternative_service_vector.empty());
9776}
9777
bncf33fb31b2016-01-29 15:22:269778// Alternative Service headers must be ignored when
9779// |parse_alternative_services| is false.
bnc54ec34b72015-08-26 19:34:569780TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:269781 session_deps_.parse_alternative_services = false;
bnc54ec34b72015-08-26 19:34:569782
9783 std::string alternative_service_http_header =
9784 GetAlternativeServiceHttpHeader();
9785
9786 MockRead data_reads[] = {
9787 MockRead("HTTP/1.1 200 OK\r\n"),
9788 MockRead(alternative_service_http_header.c_str()),
9789 MockRead("\r\n"),
9790 MockRead("hello world"),
9791 MockRead(SYNCHRONOUS, OK),
9792 };
9793
9794 HttpRequestInfo request;
9795 request.method = "GET";
9796 request.url = GURL("http://www.example.org/");
9797 request.load_flags = 0;
9798
9799 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
9800
9801 session_deps_.socket_factory->AddSocketDataProvider(&data);
9802
9803 TestCompletionCallback callback;
9804
mmenkee65e7af2015-10-13 17:16:429805 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:569806 scoped_ptr<HttpTransaction> trans(
9807 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9808
9809 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9810 EXPECT_EQ(ERR_IO_PENDING, rv);
9811
9812 HostPortPair http_host_port_pair("www.example.org", 80);
9813 HttpServerProperties& http_server_properties =
9814 *session->http_server_properties();
9815 AlternativeServiceVector alternative_service_vector =
9816 http_server_properties.GetAlternativeServices(http_host_port_pair);
9817 EXPECT_TRUE(alternative_service_vector.empty());
9818
9819 EXPECT_EQ(OK, callback.WaitForResult());
9820
9821 const HttpResponseInfo* response = trans->GetResponseInfo();
9822 ASSERT_TRUE(response != nullptr);
9823 ASSERT_TRUE(response->headers.get() != nullptr);
9824 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9825 EXPECT_FALSE(response->was_fetched_via_spdy);
9826 EXPECT_FALSE(response->was_npn_negotiated);
9827
9828 std::string response_data;
9829 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9830 EXPECT_EQ("hello world", response_data);
9831
9832 alternative_service_vector =
9833 http_server_properties.GetAlternativeServices(http_host_port_pair);
9834 EXPECT_TRUE(alternative_service_vector.empty());
9835}
9836
bncc958faa2015-07-31 18:14:529837TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:269838 session_deps_.parse_alternative_services = true;
9839 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:529840
9841 MockRead data_reads[] = {
9842 MockRead("HTTP/1.1 200 OK\r\n"),
9843 MockRead("Alt-Svc: "),
9844 MockRead(GetAlternateProtocolFromParam()),
bnc44858c82015-10-16 11:57:219845 MockRead("=\"www.example.com:443\";p=\"1.0\","),
bnc3f0118e2016-02-02 15:42:229846 MockRead(GetAlternateProtocolFromParam()),
9847 MockRead("=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:529848 MockRead("hello world"),
9849 MockRead(SYNCHRONOUS, OK),
9850 };
9851
9852 HttpRequestInfo request;
9853 request.method = "GET";
9854 request.url = GURL("http://www.example.org/");
9855 request.load_flags = 0;
9856
9857 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9858
9859 session_deps_.socket_factory->AddSocketDataProvider(&data);
9860
9861 TestCompletionCallback callback;
9862
mmenkee65e7af2015-10-13 17:16:429863 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:529864 scoped_ptr<HttpTransaction> trans(
9865 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9866
9867 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9868 EXPECT_EQ(ERR_IO_PENDING, rv);
9869
9870 HostPortPair http_host_port_pair("www.example.org", 80);
9871 HttpServerProperties& http_server_properties =
9872 *session->http_server_properties();
9873 AlternativeServiceVector alternative_service_vector =
9874 http_server_properties.GetAlternativeServices(http_host_port_pair);
9875 EXPECT_TRUE(alternative_service_vector.empty());
9876
9877 EXPECT_EQ(OK, callback.WaitForResult());
9878
9879 const HttpResponseInfo* response = trans->GetResponseInfo();
9880 ASSERT_TRUE(response != NULL);
9881 ASSERT_TRUE(response->headers.get() != NULL);
9882 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9883 EXPECT_FALSE(response->was_fetched_via_spdy);
9884 EXPECT_FALSE(response->was_npn_negotiated);
9885
9886 std::string response_data;
9887 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9888 EXPECT_EQ("hello world", response_data);
9889
9890 alternative_service_vector =
9891 http_server_properties.GetAlternativeServices(http_host_port_pair);
9892 ASSERT_EQ(2u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:389893 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:529894 alternative_service_vector[0].protocol);
9895 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9896 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc3f0118e2016-02-02 15:42:229897 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
9898 alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:529899 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
9900 EXPECT_EQ(1234, alternative_service_vector[1].port);
9901}
9902
bncf33fb31b2016-01-29 15:22:269903// Alternate Protocol headers must be honored even if
9904// |parse_alternative_services| is false.
[email protected]23e482282013-06-14 16:08:029905TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
bncf33fb31b2016-01-29 15:22:269906 session_deps_.parse_alternative_services = false;
[email protected]a2cb8122010-03-10 17:22:429907
[email protected]8a0fc822013-06-27 20:52:439908 std::string alternate_protocol_http_header =
9909 GetAlternateProtocolHttpHeader();
9910
[email protected]564b4912010-03-09 16:30:429911 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529912 MockRead("HTTP/1.1 200 OK\r\n"),
9913 MockRead(alternate_protocol_http_header.c_str()),
9914 MockRead("\r\n"),
9915 MockRead("hello world"),
9916 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:429917 };
9918
9919 HttpRequestInfo request;
9920 request.method = "GET";
bncce36dca22015-04-21 22:11:239921 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429922 request.load_flags = 0;
9923
9924 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9925
[email protected]bb88e1d32013-05-03 23:11:079926 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:429927
[email protected]49639fa2011-12-20 23:22:419928 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429929
mmenkee65e7af2015-10-13 17:16:429930 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369931 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509932 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:429933
[email protected]49639fa2011-12-20 23:22:419934 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429935 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:539936
bncce36dca22015-04-21 22:11:239937 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:559938 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:539939 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:109940 AlternativeServiceVector alternative_service_vector =
9941 http_server_properties.GetAlternativeServices(http_host_port_pair);
9942 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:429943
9944 EXPECT_EQ(OK, callback.WaitForResult());
9945
9946 const HttpResponseInfo* response = trans->GetResponseInfo();
9947 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509948 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429949 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539950 EXPECT_FALSE(response->was_fetched_via_spdy);
9951 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:429952
9953 std::string response_data;
9954 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9955 EXPECT_EQ("hello world", response_data);
9956
bncd9b132e2015-07-08 05:16:109957 alternative_service_vector =
9958 http_server_properties.GetAlternativeServices(http_host_port_pair);
9959 ASSERT_EQ(1u, alternative_service_vector.size());
9960 EXPECT_EQ(443, alternative_service_vector[0].port);
rdsmithebb50aa2015-11-12 03:44:389961 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncd9b132e2015-07-08 05:16:109962 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:429963}
9964
rch89c6e102015-03-18 18:56:529965TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
rch3f4b8452016-02-23 16:59:329966 session_deps_.parse_alternative_services = false;
bncf33fb31b2016-01-29 15:22:269967 session_deps_.enable_alternative_service_with_different_host = false;
rch89c6e102015-03-18 18:56:529968
9969 MockRead data_reads[] = {
9970 MockRead("HTTP/1.1 200 OK\r\n"),
9971 MockRead("Alternate-Protocol: \r\n\r\n"),
9972 MockRead("hello world"),
9973 MockRead(SYNCHRONOUS, OK),
9974 };
9975
9976 HttpRequestInfo request;
9977 request.method = "GET";
bncce36dca22015-04-21 22:11:239978 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:529979 request.load_flags = 0;
9980
9981 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9982
9983 session_deps_.socket_factory->AddSocketDataProvider(&data);
9984
9985 TestCompletionCallback callback;
9986
mmenkee65e7af2015-10-13 17:16:429987 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rch89c6e102015-03-18 18:56:529988
bncce36dca22015-04-21 22:11:239989 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:529990 HttpServerProperties& http_server_properties =
9991 *session->http_server_properties();
bnccacc0992015-03-20 20:22:229992 AlternativeService alternative_service(QUIC, "", 80);
bnc7dc7e1b42015-07-28 14:43:129993 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
rchdc7b9052016-03-17 20:51:509994 http_server_properties.SetAlternativeService(http_host_port_pair,
9995 alternative_service, expiration);
bnccacc0992015-03-20 20:22:229996
bncd9b132e2015-07-08 05:16:109997 AlternativeServiceVector alternative_service_vector =
9998 http_server_properties.GetAlternativeServices(http_host_port_pair);
9999 ASSERT_EQ(1u, alternative_service_vector.size());
10000 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:5210001
10002 scoped_ptr<HttpTransaction> trans(
10003 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10004
10005 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10006 EXPECT_EQ(ERR_IO_PENDING, rv);
10007
10008 EXPECT_EQ(OK, callback.WaitForResult());
10009
10010 const HttpResponseInfo* response = trans->GetResponseInfo();
10011 ASSERT_TRUE(response != NULL);
10012 ASSERT_TRUE(response->headers.get() != NULL);
10013 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10014 EXPECT_FALSE(response->was_fetched_via_spdy);
10015 EXPECT_FALSE(response->was_npn_negotiated);
10016
10017 std::string response_data;
10018 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10019 EXPECT_EQ("hello world", response_data);
10020
bncd9b132e2015-07-08 05:16:1010021 alternative_service_vector =
10022 http_server_properties.GetAlternativeServices(http_host_port_pair);
10023 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:5210024}
10025
bncf33fb31b2016-01-29 15:22:2610026// When |session_deps_.parse_alternative_services = true| and the response has
10027// an Alt-Svc header, then the Alternate-Protocol header is not parsed.
bncc958faa2015-07-31 18:14:5210028TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
bncf33fb31b2016-01-29 15:22:2610029 session_deps_.parse_alternative_services = true;
10030 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:5210031
10032 std::string alternative_service_http_header =
10033 GetAlternativeServiceHttpHeader();
10034 std::string alternate_protocol_http_header = GetAlternateProtocolHttpHeader();
10035
10036 MockRead data_reads[] = {
10037 MockRead("HTTP/1.1 200 OK\r\n"),
10038 MockRead(alternative_service_http_header.c_str()),
10039 MockRead(alternate_protocol_http_header.c_str()),
10040 MockRead("\r\n"),
10041 MockRead("hello world"),
10042 MockRead(SYNCHRONOUS, OK),
10043 };
10044
10045 HttpRequestInfo request;
10046 request.method = "GET";
10047 request.url = GURL("http://www.example.org/");
10048 request.load_flags = 0;
10049
10050 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10051
10052 session_deps_.socket_factory->AddSocketDataProvider(&data);
10053
10054 TestCompletionCallback callback;
10055
mmenkee65e7af2015-10-13 17:16:4210056 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncc958faa2015-07-31 18:14:5210057 scoped_ptr<HttpTransaction> trans(
10058 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10059
10060 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10061 EXPECT_EQ(ERR_IO_PENDING, rv);
10062
10063 HostPortPair http_host_port_pair("www.example.org", 80);
10064 HttpServerProperties& http_server_properties =
10065 *session->http_server_properties();
10066 AlternativeServiceVector alternative_service_vector =
10067 http_server_properties.GetAlternativeServices(http_host_port_pair);
10068 EXPECT_TRUE(alternative_service_vector.empty());
10069
10070 EXPECT_EQ(OK, callback.WaitForResult());
10071
10072 const HttpResponseInfo* response = trans->GetResponseInfo();
10073 ASSERT_TRUE(response != NULL);
10074 ASSERT_TRUE(response->headers.get() != NULL);
10075 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10076 EXPECT_FALSE(response->was_fetched_via_spdy);
10077 EXPECT_FALSE(response->was_npn_negotiated);
10078
10079 std::string response_data;
10080 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10081 EXPECT_EQ("hello world", response_data);
10082
10083 alternative_service_vector =
10084 http_server_properties.GetAlternativeServices(http_host_port_pair);
10085 ASSERT_EQ(1u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:3810086 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:5210087 alternative_service_vector[0].protocol);
10088 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
10089 EXPECT_EQ(443, alternative_service_vector[0].port);
10090}
10091
bncf33fb31b2016-01-29 15:22:2610092// When |enable_alternative_service_with_different_host| is false, do not
10093// observe alternative service entries that point to a different host.
bnc54ec34b72015-08-26 19:34:5610094TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
bncf33fb31b2016-01-29 15:22:2610095 session_deps_.parse_alternative_services = true;
10096 session_deps_.enable_alternative_service_with_different_host = false;
bnc54ec34b72015-08-26 19:34:5610097
10098 HttpRequestInfo request;
10099 request.method = "GET";
10100 request.url = GURL("http://www.example.org/");
10101 request.load_flags = 0;
10102
10103 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10104 StaticSocketDataProvider first_data;
10105 first_data.set_connect_data(mock_connect);
10106 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10107
10108 MockRead data_reads[] = {
10109 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10110 MockRead(ASYNC, OK),
10111 };
10112 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
10113 nullptr, 0);
10114 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10115
mmenkee65e7af2015-10-13 17:16:4210116 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:5610117
10118 base::WeakPtr<HttpServerProperties> http_server_properties =
10119 session->http_server_properties();
10120 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810121 AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
10122 80);
bnc54ec34b72015-08-26 19:34:5610123 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10124 http_server_properties->SetAlternativeService(
rchdc7b9052016-03-17 20:51:5010125 HostPortPair::FromURL(request.url), alternative_service, expiration);
bnc54ec34b72015-08-26 19:34:5610126
10127 scoped_ptr<HttpTransaction> trans(
10128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10129 TestCompletionCallback callback;
10130
10131 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10132 // The connetion to origin was refused, and the alternative service should not
10133 // be used (even though mock data are there), therefore the request should
10134 // fail.
10135 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
10136}
10137
zhongyi48704c182015-12-07 07:52:0210138TEST_P(HttpNetworkTransactionTest, IdentifyQuicBroken) {
10139 HostPortPair origin("origin.example.org", 443);
10140 HostPortPair alternative("alternative.example.org", 443);
10141 std::string origin_url = "https://origin.example.org:443";
10142 std::string alternative_url = "https://alternative.example.org:443";
10143
10144 // Negotiate HTTP/1.1 with alternative.example.org.
10145 SSLSocketDataProvider ssl(ASYNC, OK);
10146 ssl.SetNextProto(kProtoHTTP11);
10147 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10148
10149 // HTTP/1.1 data for request.
10150 MockWrite http_writes[] = {
10151 MockWrite("GET / HTTP/1.1\r\n"
10152 "Host: alternative.example.org\r\n"
10153 "Connection: keep-alive\r\n\r\n"),
10154 };
10155
10156 MockRead http_reads[] = {
10157 MockRead("HTTP/1.1 200 OK\r\n"
10158 "Content-Type: text/html; charset=iso-8859-1\r\n"
10159 "Content-Length: 40\r\n\r\n"
10160 "first HTTP/1.1 response from alternative"),
10161 };
10162 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10163 http_writes, arraysize(http_writes));
10164 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10165
10166 StaticSocketDataProvider data_refused;
10167 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10168 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10169
10170 // Set up a QUIC alternative service for origin.
bncf33fb31b2016-01-29 15:22:2610171 session_deps_.parse_alternative_services = true;
10172 session_deps_.enable_alternative_service_with_different_host = false;
zhongyi48704c182015-12-07 07:52:0210173 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10174 base::WeakPtr<HttpServerProperties> http_server_properties =
10175 session->http_server_properties();
10176 AlternativeService alternative_service(QUIC, alternative);
10177 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10178 http_server_properties->SetAlternativeService(origin, alternative_service,
rchdc7b9052016-03-17 20:51:5010179 expiration);
zhongyi48704c182015-12-07 07:52:0210180 // Mark the QUIC alternative service as broken.
10181 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10182
10183 scoped_ptr<HttpTransaction> trans(
10184 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10185 HttpRequestInfo request;
10186 request.method = "GET";
10187 request.url = GURL(origin_url);
10188 request.load_flags = 0;
10189 TestCompletionCallback callback;
10190 NetErrorDetails details;
10191 EXPECT_FALSE(details.quic_broken);
10192
10193 trans->Start(&request, callback.callback(), BoundNetLog());
10194 trans->PopulateNetErrorDetails(&details);
10195 EXPECT_TRUE(details.quic_broken);
10196}
10197
10198TEST_P(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
10199 HostPortPair origin("origin.example.org", 443);
10200 HostPortPair alternative1("alternative1.example.org", 443);
10201 HostPortPair alternative2("alternative2.example.org", 443);
10202 std::string origin_url = "https://origin.example.org:443";
10203 std::string alternative_url1 = "https://alternative1.example.org:443";
10204 std::string alternative_url2 = "https://alternative2.example.org:443";
10205
10206 // Negotiate HTTP/1.1 with alternative1.example.org.
10207 SSLSocketDataProvider ssl(ASYNC, OK);
10208 ssl.SetNextProto(kProtoHTTP11);
10209 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10210
10211 // HTTP/1.1 data for request.
10212 MockWrite http_writes[] = {
10213 MockWrite("GET / HTTP/1.1\r\n"
10214 "Host: alternative1.example.org\r\n"
10215 "Connection: keep-alive\r\n\r\n"),
10216 };
10217
10218 MockRead http_reads[] = {
10219 MockRead("HTTP/1.1 200 OK\r\n"
10220 "Content-Type: text/html; charset=iso-8859-1\r\n"
10221 "Content-Length: 40\r\n\r\n"
10222 "first HTTP/1.1 response from alternative1"),
10223 };
10224 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10225 http_writes, arraysize(http_writes));
10226 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10227
10228 StaticSocketDataProvider data_refused;
10229 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10230 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10231
bncf33fb31b2016-01-29 15:22:2610232 session_deps_.parse_alternative_services = true;
10233 session_deps_.enable_alternative_service_with_different_host = true;
zhongyi48704c182015-12-07 07:52:0210234 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10235 base::WeakPtr<HttpServerProperties> http_server_properties =
10236 session->http_server_properties();
10237
10238 // Set up two QUIC alternative services for origin.
10239 AlternativeServiceInfoVector alternative_service_info_vector;
10240 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10241
10242 AlternativeService alternative_service1(QUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010243 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210244 expiration);
10245 alternative_service_info_vector.push_back(alternative_service_info1);
10246 AlternativeService alternative_service2(QUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010247 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210248 expiration);
10249 alternative_service_info_vector.push_back(alternative_service_info2);
10250
10251 http_server_properties->SetAlternativeServices(
10252 origin, alternative_service_info_vector);
10253
10254 // Mark one of the QUIC alternative service as broken.
10255 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10256
10257 const AlternativeServiceVector alternative_service_vector =
10258 http_server_properties->GetAlternativeServices(origin);
10259
10260 scoped_ptr<HttpTransaction> trans(
10261 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10262 HttpRequestInfo request;
10263 request.method = "GET";
10264 request.url = GURL(origin_url);
10265 request.load_flags = 0;
10266 TestCompletionCallback callback;
10267 NetErrorDetails details;
10268 EXPECT_FALSE(details.quic_broken);
10269
10270 trans->Start(&request, callback.callback(), BoundNetLog());
10271 trans->PopulateNetErrorDetails(&details);
10272 EXPECT_FALSE(details.quic_broken);
10273}
10274
[email protected]23e482282013-06-14 16:08:0210275TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310276 MarkBrokenAlternateProtocolAndFallback) {
bncf33fb31b2016-01-29 15:22:2610277 session_deps_.parse_alternative_services = true;
10278 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]564b4912010-03-09 16:30:4210279
10280 HttpRequestInfo request;
10281 request.method = "GET";
bncce36dca22015-04-21 22:11:2310282 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210283 request.load_flags = 0;
10284
[email protected]d973e99a2012-02-17 21:02:3610285 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210286 StaticSocketDataProvider first_data;
10287 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710288 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:4210289
10290 MockRead data_reads[] = {
10291 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10292 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610293 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210294 };
10295 StaticSocketDataProvider second_data(
10296 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710297 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210298
mmenkee65e7af2015-10-13 17:16:4210299 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210300
[email protected]30d4c022013-07-18 22:58:1610301 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310302 session->http_server_properties();
bnc8445b3002015-03-13 01:57:0910303 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:1110304 // Port must be < 1024, or the header will be ignored (since initial port was
10305 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010306 const AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810307 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bncd9b132e2015-07-08 05:16:1010308 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210309 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10310 http_server_properties->SetAlternativeService(
rchdc7b9052016-03-17 20:51:5010311 host_port_pair, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4210312
[email protected]262eec82013-03-19 21:01:3610313 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010314 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110315 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210316
[email protected]49639fa2011-12-20 23:22:4110317 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:4210318 EXPECT_EQ(ERR_IO_PENDING, rv);
10319 EXPECT_EQ(OK, callback.WaitForResult());
10320
10321 const HttpResponseInfo* response = trans->GetResponseInfo();
10322 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010323 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:4210324 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10325
10326 std::string response_data;
10327 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10328 EXPECT_EQ("hello world", response_data);
10329
bncd9b132e2015-07-08 05:16:1010330 const AlternativeServiceVector alternative_service_vector =
10331 http_server_properties->GetAlternativeServices(host_port_pair);
10332 ASSERT_EQ(1u, alternative_service_vector.size());
10333 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10334 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10335 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210336}
10337
bnc55ff9da2015-08-19 18:42:3510338// Ensure that we are not allowed to redirect traffic via an alternate protocol
10339// to an unrestricted (port >= 1024) when the original traffic was on a
10340// restricted port (port < 1024). Ensure that we can redirect in all other
10341// cases.
[email protected]23e482282013-06-14 16:08:0210342TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310343 AlternateProtocolPortRestrictedBlocked) {
bncf33fb31b2016-01-29 15:22:2610344 session_deps_.parse_alternative_services = true;
10345 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110346
10347 HttpRequestInfo restricted_port_request;
10348 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310349 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110350 restricted_port_request.load_flags = 0;
10351
[email protected]d973e99a2012-02-17 21:02:3610352 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110353 StaticSocketDataProvider first_data;
10354 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710355 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110356
10357 MockRead data_reads[] = {
10358 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10359 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610360 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110361 };
10362 StaticSocketDataProvider second_data(
10363 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710364 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110365
mmenkee65e7af2015-10-13 17:16:4210366 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110367
[email protected]30d4c022013-07-18 22:58:1610368 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310369 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110370 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210371 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810372 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210373 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210374 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210375 http_server_properties->SetAlternativeService(
10376 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010377 expiration);
[email protected]3912662a32011-10-04 00:51:1110378
[email protected]262eec82013-03-19 21:01:3610379 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010380 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110381 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110382
[email protected]49639fa2011-12-20 23:22:4110383 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610384 &restricted_port_request,
10385 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110386 EXPECT_EQ(ERR_IO_PENDING, rv);
10387 // Invalid change to unrestricted port should fail.
10388 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:1910389}
[email protected]3912662a32011-10-04 00:51:1110390
bnc55ff9da2015-08-19 18:42:3510391// Ensure that we are allowed to redirect traffic via an alternate protocol to
10392// an unrestricted (port >= 1024) when the original traffic was on a restricted
10393// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:0210394TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:1910395 AlternateProtocolPortRestrictedPermitted) {
bncf33fb31b2016-01-29 15:22:2610396 session_deps_.parse_alternative_services = true;
10397 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]bb88e1d32013-05-03 23:11:0710398 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910399
10400 HttpRequestInfo restricted_port_request;
10401 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310402 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910403 restricted_port_request.load_flags = 0;
10404
10405 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10406 StaticSocketDataProvider first_data;
10407 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710408 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910409
10410 MockRead data_reads[] = {
10411 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10412 MockRead("hello world"),
10413 MockRead(ASYNC, OK),
10414 };
10415 StaticSocketDataProvider second_data(
10416 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710417 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:1910418
mmenkee65e7af2015-10-13 17:16:4210419 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910420
[email protected]30d4c022013-07-18 22:58:1610421 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910422 session->http_server_properties();
10423 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210424 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810425 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210426 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210427 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210428 http_server_properties->SetAlternativeService(
10429 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010430 expiration);
[email protected]c54c6962013-02-01 04:53:1910431
[email protected]262eec82013-03-19 21:01:3610432 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010433 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:1910434 TestCompletionCallback callback;
10435
10436 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:3610437 &restricted_port_request,
10438 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:1910439 // Change to unrestricted port should succeed.
10440 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110441}
10442
bnc55ff9da2015-08-19 18:42:3510443// Ensure that we are not allowed to redirect traffic via an alternate protocol
10444// to an unrestricted (port >= 1024) when the original traffic was on a
10445// restricted port (port < 1024). Ensure that we can redirect in all other
10446// cases.
[email protected]23e482282013-06-14 16:08:0210447TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310448 AlternateProtocolPortRestrictedAllowed) {
bncf33fb31b2016-01-29 15:22:2610449 session_deps_.parse_alternative_services = true;
10450 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110451
10452 HttpRequestInfo restricted_port_request;
10453 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310454 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110455 restricted_port_request.load_flags = 0;
10456
[email protected]d973e99a2012-02-17 21:02:3610457 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110458 StaticSocketDataProvider first_data;
10459 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710460 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110461
10462 MockRead data_reads[] = {
10463 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10464 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610465 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110466 };
10467 StaticSocketDataProvider second_data(
10468 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710469 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110470
mmenkee65e7af2015-10-13 17:16:4210471 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110472
[email protected]30d4c022013-07-18 22:58:1610473 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310474 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110475 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210476 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810477 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210478 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210479 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210480 http_server_properties->SetAlternativeService(
10481 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010482 expiration);
[email protected]3912662a32011-10-04 00:51:1110483
[email protected]262eec82013-03-19 21:01:3610484 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010485 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110486 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110487
[email protected]49639fa2011-12-20 23:22:4110488 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610489 &restricted_port_request,
10490 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110491 EXPECT_EQ(ERR_IO_PENDING, rv);
10492 // Valid change to restricted port should pass.
10493 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110494}
10495
bnc55ff9da2015-08-19 18:42:3510496// Ensure that we are not allowed to redirect traffic via an alternate protocol
10497// to an unrestricted (port >= 1024) when the original traffic was on a
10498// restricted port (port < 1024). Ensure that we can redirect in all other
10499// cases.
[email protected]23e482282013-06-14 16:08:0210500TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310501 AlternateProtocolPortUnrestrictedAllowed1) {
bncf33fb31b2016-01-29 15:22:2610502 session_deps_.parse_alternative_services = true;
10503 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110504
10505 HttpRequestInfo unrestricted_port_request;
10506 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310507 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110508 unrestricted_port_request.load_flags = 0;
10509
[email protected]d973e99a2012-02-17 21:02:3610510 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110511 StaticSocketDataProvider first_data;
10512 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710513 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110514
10515 MockRead data_reads[] = {
10516 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10517 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610518 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110519 };
10520 StaticSocketDataProvider second_data(
10521 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710522 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110523
mmenkee65e7af2015-10-13 17:16:4210524 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110525
[email protected]30d4c022013-07-18 22:58:1610526 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310527 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110528 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210529 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810530 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210531 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210532 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210533 http_server_properties->SetAlternativeService(
10534 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010535 expiration);
[email protected]3912662a32011-10-04 00:51:1110536
[email protected]262eec82013-03-19 21:01:3610537 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010538 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110539 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110540
[email protected]49639fa2011-12-20 23:22:4110541 int rv = trans->Start(
10542 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110543 EXPECT_EQ(ERR_IO_PENDING, rv);
10544 // Valid change to restricted port should pass.
10545 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110546}
10547
bnc55ff9da2015-08-19 18:42:3510548// Ensure that we are not allowed to redirect traffic via an alternate protocol
10549// to an unrestricted (port >= 1024) when the original traffic was on a
10550// restricted port (port < 1024). Ensure that we can redirect in all other
10551// cases.
[email protected]23e482282013-06-14 16:08:0210552TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310553 AlternateProtocolPortUnrestrictedAllowed2) {
bncf33fb31b2016-01-29 15:22:2610554 session_deps_.parse_alternative_services = true;
10555 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110556
10557 HttpRequestInfo unrestricted_port_request;
10558 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310559 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110560 unrestricted_port_request.load_flags = 0;
10561
[email protected]d973e99a2012-02-17 21:02:3610562 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110563 StaticSocketDataProvider first_data;
10564 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710565 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110566
10567 MockRead data_reads[] = {
10568 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10569 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610570 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110571 };
10572 StaticSocketDataProvider second_data(
10573 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710574 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110575
mmenkee65e7af2015-10-13 17:16:4210576 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110577
[email protected]30d4c022013-07-18 22:58:1610578 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:5310579 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210580 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:2210581 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810582 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210583 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210584 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210585 http_server_properties->SetAlternativeService(
10586 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010587 expiration);
[email protected]3912662a32011-10-04 00:51:1110588
[email protected]262eec82013-03-19 21:01:3610589 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010590 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110591 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110592
[email protected]49639fa2011-12-20 23:22:4110593 int rv = trans->Start(
10594 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110595 EXPECT_EQ(ERR_IO_PENDING, rv);
10596 // Valid change to an unrestricted port should pass.
10597 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110598}
10599
bnc55ff9da2015-08-19 18:42:3510600// Ensure that we are not allowed to redirect traffic via an alternate protocol
10601// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10602// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:2310603TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bncf33fb31b2016-01-29 15:22:2610604 session_deps_.parse_alternative_services = true;
10605 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]eb6234e2012-01-19 01:50:0210606
10607 HttpRequestInfo request;
10608 request.method = "GET";
bncce36dca22015-04-21 22:11:2310609 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210610 request.load_flags = 0;
10611
10612 // The alternate protocol request will error out before we attempt to connect,
10613 // so only the standard HTTP request will try to connect.
10614 MockRead data_reads[] = {
10615 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10616 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610617 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210618 };
10619 StaticSocketDataProvider data(
10620 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710621 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210622
mmenkee65e7af2015-10-13 17:16:4210623 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210624
[email protected]30d4c022013-07-18 22:58:1610625 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210626 session->http_server_properties();
10627 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:2210628 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810629 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210630 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210631 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210632 http_server_properties->SetAlternativeService(
rchdc7b9052016-03-17 20:51:5010633 HostPortPair::FromURL(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210634
[email protected]262eec82013-03-19 21:01:3610635 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010636 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:0210637 TestCompletionCallback callback;
10638
10639 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10640 EXPECT_EQ(ERR_IO_PENDING, rv);
10641 // The HTTP request should succeed.
10642 EXPECT_EQ(OK, callback.WaitForResult());
10643
[email protected]eb6234e2012-01-19 01:50:0210644 const HttpResponseInfo* response = trans->GetResponseInfo();
10645 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010646 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:0210647 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10648
10649 std::string response_data;
10650 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10651 EXPECT_EQ("hello world", response_data);
10652}
10653
[email protected]23e482282013-06-14 16:08:0210654TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
rch3f4b8452016-02-23 16:59:3210655 session_deps_.parse_alternative_services = false;
bncf33fb31b2016-01-29 15:22:2610656 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2ff8b312010-04-26 22:20:5410657
10658 HttpRequestInfo request;
10659 request.method = "GET";
bncce36dca22015-04-21 22:11:2310660 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410661 request.load_flags = 0;
10662
[email protected]8a0fc822013-06-27 20:52:4310663 std::string alternate_protocol_http_header =
10664 GetAlternateProtocolHttpHeader();
10665
[email protected]2ff8b312010-04-26 22:20:5410666 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210667 MockRead("HTTP/1.1 200 OK\r\n"),
10668 MockRead(alternate_protocol_http_header.c_str()),
10669 MockRead("\r\n"),
10670 MockRead("hello world"),
10671 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10672 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410673
10674 StaticSocketDataProvider first_transaction(
10675 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710676 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410677
[email protected]8ddf8322012-02-23 18:08:0610678 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810679 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310680 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10681 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710682 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410683
bncb03b1092016-04-06 11:19:5510684 scoped_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4910685 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310686 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410687
bncb03b1092016-04-06 11:19:5510688 scoped_ptr<SpdySerializedFrame> resp(
10689 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10690 scoped_ptr<SpdySerializedFrame> data(
10691 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410692 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310693 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410694 };
10695
rch8e6c6c42015-05-01 14:05:1310696 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10697 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710698 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410699
[email protected]d973e99a2012-02-17 21:02:3610700 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510701 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10702 NULL, 0, NULL, 0);
10703 hanging_non_alternate_protocol_socket.set_connect_data(
10704 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710705 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510706 &hanging_non_alternate_protocol_socket);
10707
[email protected]49639fa2011-12-20 23:22:4110708 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410709
mmenkee65e7af2015-10-13 17:16:4210710 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610711 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010712 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410713
[email protected]49639fa2011-12-20 23:22:4110714 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410715 EXPECT_EQ(ERR_IO_PENDING, rv);
10716 EXPECT_EQ(OK, callback.WaitForResult());
10717
10718 const HttpResponseInfo* response = trans->GetResponseInfo();
10719 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010720 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410721 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10722
10723 std::string response_data;
10724 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10725 EXPECT_EQ("hello world", response_data);
10726
[email protected]90499482013-06-01 00:39:5010727 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410728
[email protected]49639fa2011-12-20 23:22:4110729 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410730 EXPECT_EQ(ERR_IO_PENDING, rv);
10731 EXPECT_EQ(OK, callback.WaitForResult());
10732
10733 response = trans->GetResponseInfo();
10734 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010735 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0210736 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310737 EXPECT_TRUE(response->was_fetched_via_spdy);
10738 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410739
10740 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10741 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410742}
10743
[email protected]23e482282013-06-14 16:08:0210744TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
rch3f4b8452016-02-23 16:59:3210745 session_deps_.parse_alternative_services = false;
bncf33fb31b2016-01-29 15:22:2610746 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d6728692011-03-12 01:39:5510747
10748 HttpRequestInfo request;
10749 request.method = "GET";
bncce36dca22015-04-21 22:11:2310750 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510751 request.load_flags = 0;
10752
[email protected]8a0fc822013-06-27 20:52:4310753 std::string alternate_protocol_http_header =
10754 GetAlternateProtocolHttpHeader();
10755
[email protected]2d6728692011-03-12 01:39:5510756 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210757 MockRead("HTTP/1.1 200 OK\r\n"),
10758 MockRead(alternate_protocol_http_header.c_str()),
10759 MockRead("\r\n"),
10760 MockRead("hello world"),
10761 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10762 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510763 };
10764
10765 StaticSocketDataProvider first_transaction(
10766 data_reads, arraysize(data_reads), NULL, 0);
10767 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:0710768 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510769
[email protected]d973e99a2012-02-17 21:02:3610770 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810771 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10772 hanging_socket1.set_connect_data(never_finishing_connect);
[email protected]2d6728692011-03-12 01:39:5510773 // Socket 2 and 3 are the hanging Alternate-Protocol and
10774 // non-Alternate-Protocol jobs from the 2nd transaction.
mmenkecc2298e2015-12-07 18:20:1810775 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10776
10777 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10778 hanging_socket2.set_connect_data(never_finishing_connect);
10779 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510780
[email protected]8ddf8322012-02-23 18:08:0610781 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810782 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310783 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10784 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710785 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510786
bncb03b1092016-04-06 11:19:5510787 scoped_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4910788 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncb03b1092016-04-06 11:19:5510789 scoped_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4910790 spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:5510791 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310792 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:5510793 };
bncb03b1092016-04-06 11:19:5510794 scoped_ptr<SpdySerializedFrame> resp1(
10795 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10796 scoped_ptr<SpdySerializedFrame> data1(
10797 spdy_util_.ConstructSpdyBodyFrame(1, true));
10798 scoped_ptr<SpdySerializedFrame> resp2(
10799 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
10800 scoped_ptr<SpdySerializedFrame> data2(
10801 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510802 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310803 CreateMockRead(*resp1, 2),
10804 CreateMockRead(*data1, 3),
10805 CreateMockRead(*resp2, 4),
10806 CreateMockRead(*data2, 5),
10807 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510808 };
10809
rch8e6c6c42015-05-01 14:05:1310810 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10811 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:5510812 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710813 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510814
10815 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
mmenkecc2298e2015-12-07 18:20:1810816 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10817 hanging_socket3.set_connect_data(never_finishing_connect);
10818 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510819
mmenkee65e7af2015-10-13 17:16:4210820 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110821 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010822 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510823
[email protected]49639fa2011-12-20 23:22:4110824 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510825 EXPECT_EQ(ERR_IO_PENDING, rv);
10826 EXPECT_EQ(OK, callback1.WaitForResult());
10827
10828 const HttpResponseInfo* response = trans1.GetResponseInfo();
10829 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010830 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510831 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10832
10833 std::string response_data;
10834 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
10835 EXPECT_EQ("hello world", response_data);
10836
[email protected]49639fa2011-12-20 23:22:4110837 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5010838 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110839 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510840 EXPECT_EQ(ERR_IO_PENDING, rv);
10841
[email protected]49639fa2011-12-20 23:22:4110842 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5010843 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4110844 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510845 EXPECT_EQ(ERR_IO_PENDING, rv);
10846
10847 EXPECT_EQ(OK, callback2.WaitForResult());
10848 EXPECT_EQ(OK, callback3.WaitForResult());
10849
10850 response = trans2.GetResponseInfo();
10851 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010852 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0210853 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5510854 EXPECT_TRUE(response->was_fetched_via_spdy);
10855 EXPECT_TRUE(response->was_npn_negotiated);
10856 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
10857 EXPECT_EQ("hello!", response_data);
10858
10859 response = trans3.GetResponseInfo();
10860 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010861 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0210862 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5510863 EXPECT_TRUE(response->was_fetched_via_spdy);
10864 EXPECT_TRUE(response->was_npn_negotiated);
10865 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
10866 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5510867}
10868
[email protected]23e482282013-06-14 16:08:0210869TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
rch3f4b8452016-02-23 16:59:3210870 session_deps_.parse_alternative_services = false;
bncf33fb31b2016-01-29 15:22:2610871 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d6728692011-03-12 01:39:5510872
10873 HttpRequestInfo request;
10874 request.method = "GET";
bncce36dca22015-04-21 22:11:2310875 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510876 request.load_flags = 0;
10877
[email protected]8a0fc822013-06-27 20:52:4310878 std::string alternate_protocol_http_header =
10879 GetAlternateProtocolHttpHeader();
10880
[email protected]2d6728692011-03-12 01:39:5510881 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210882 MockRead("HTTP/1.1 200 OK\r\n"),
10883 MockRead(alternate_protocol_http_header.c_str()),
10884 MockRead("\r\n"),
10885 MockRead("hello world"),
10886 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10887 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510888 };
10889
10890 StaticSocketDataProvider first_transaction(
10891 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710892 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510893
[email protected]8ddf8322012-02-23 18:08:0610894 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810895 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0710896 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510897
[email protected]d973e99a2012-02-17 21:02:3610898 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510899 StaticSocketDataProvider hanging_alternate_protocol_socket(
10900 NULL, 0, NULL, 0);
10901 hanging_alternate_protocol_socket.set_connect_data(
10902 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710903 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510904 &hanging_alternate_protocol_socket);
10905
10906 // 2nd request is just a copy of the first one, over HTTP again.
mmenkecc2298e2015-12-07 18:20:1810907 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
10908 NULL, 0);
10909 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
[email protected]2d6728692011-03-12 01:39:5510910
[email protected]49639fa2011-12-20 23:22:4110911 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5510912
mmenkee65e7af2015-10-13 17:16:4210913 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610914 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010915 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510916
[email protected]49639fa2011-12-20 23:22:4110917 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510918 EXPECT_EQ(ERR_IO_PENDING, rv);
10919 EXPECT_EQ(OK, callback.WaitForResult());
10920
10921 const HttpResponseInfo* response = trans->GetResponseInfo();
10922 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010923 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510924 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10925
10926 std::string response_data;
10927 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10928 EXPECT_EQ("hello world", response_data);
10929
[email protected]90499482013-06-01 00:39:5010930 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5510931
[email protected]49639fa2011-12-20 23:22:4110932 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510933 EXPECT_EQ(ERR_IO_PENDING, rv);
10934 EXPECT_EQ(OK, callback.WaitForResult());
10935
10936 response = trans->GetResponseInfo();
10937 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010938 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:5510939 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10940 EXPECT_FALSE(response->was_fetched_via_spdy);
10941 EXPECT_FALSE(response->was_npn_negotiated);
10942
10943 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10944 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5510945}
10946
[email protected]631f1322010-04-30 17:59:1110947class CapturingProxyResolver : public ProxyResolver {
10948 public:
sammce90c9212015-05-27 23:43:3510949 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2010950 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1110951
dchengb03027d2014-10-21 12:00:2010952 int GetProxyForURL(const GURL& url,
10953 ProxyInfo* results,
10954 const CompletionCallback& callback,
eroman9c8f4242016-02-29 21:16:5410955 RequestHandle* request,
dchengb03027d2014-10-21 12:00:2010956 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4010957 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
10958 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4210959 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1110960 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4210961 return OK;
[email protected]631f1322010-04-30 17:59:1110962 }
10963
eroman9c8f4242016-02-29 21:16:5410964 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
10965
10966 LoadState GetLoadState(RequestHandle request) const override {
10967 NOTREACHED();
10968 return LOAD_STATE_IDLE;
10969 }
10970
[email protected]24476402010-07-20 20:55:1710971 const std::vector<GURL>& resolved() const { return resolved_; }
10972
10973 private:
[email protected]631f1322010-04-30 17:59:1110974 std::vector<GURL> resolved_;
10975
10976 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
10977};
10978
sammce64b2362015-04-29 03:50:2310979class CapturingProxyResolverFactory : public ProxyResolverFactory {
10980 public:
10981 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
10982 : ProxyResolverFactory(false), resolver_(resolver) {}
10983
10984 int CreateProxyResolver(
10985 const scoped_refptr<ProxyResolverScriptData>& pac_script,
10986 scoped_ptr<ProxyResolver>* resolver,
10987 const net::CompletionCallback& callback,
10988 scoped_ptr<Request>* request) override {
10989 resolver->reset(new ForwardingProxyResolver(resolver_));
10990 return OK;
10991 }
10992
10993 private:
10994 ProxyResolver* resolver_;
10995};
10996
[email protected]23e482282013-06-14 16:08:0210997TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310998 UseAlternateProtocolForTunneledNpnSpdy) {
rch3f4b8452016-02-23 16:59:3210999 session_deps_.parse_alternative_services = false;
bncf33fb31b2016-01-29 15:22:2611000 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]631f1322010-04-30 17:59:1111001
11002 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211003 proxy_config.set_auto_detect(true);
11004 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111005
sammc5dd160c2015-04-02 02:43:1311006 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711007 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:0411008 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)),
sammc5dd160c2015-04-02 02:43:1311009 make_scoped_ptr(
sammce64b2362015-04-29 03:50:2311010 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:3811011 NULL));
vishal.b62985ca92015-04-17 08:45:5111012 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711013 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111014
11015 HttpRequestInfo request;
11016 request.method = "GET";
bncce36dca22015-04-21 22:11:2311017 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111018 request.load_flags = 0;
11019
[email protected]8a0fc822013-06-27 20:52:4311020 std::string alternate_protocol_http_header =
11021 GetAlternateProtocolHttpHeader();
11022
[email protected]631f1322010-04-30 17:59:1111023 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211024 MockRead("HTTP/1.1 200 OK\r\n"),
11025 MockRead(alternate_protocol_http_header.c_str()),
11026 MockRead("\r\n"),
11027 MockRead("hello world"),
11028 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11029 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111030 };
11031
11032 StaticSocketDataProvider first_transaction(
11033 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711034 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1111035
[email protected]8ddf8322012-02-23 18:08:0611036 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811037 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2311038 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11039 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0711040 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1111041
bncb03b1092016-04-06 11:19:5511042 scoped_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911043 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1111044 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311045 MockWrite(ASYNC, 0,
11046 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711047 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311048 "Proxy-Connection: keep-alive\r\n\r\n"),
11049 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1111050 };
11051
[email protected]d911f1b2010-05-05 22:39:4211052 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11053
bncb03b1092016-04-06 11:19:5511054 scoped_ptr<SpdySerializedFrame> resp(
11055 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11056 scoped_ptr<SpdySerializedFrame> data(
11057 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111058 MockRead spdy_reads[] = {
mmenkee24011922015-12-17 22:12:5911059 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(*resp.get(), 3),
11060 CreateMockRead(*data.get(), 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111061 };
11062
rch8e6c6c42015-05-01 14:05:1311063 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11064 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711065 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111066
[email protected]d973e99a2012-02-17 21:02:3611067 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511068 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11069 NULL, 0, NULL, 0);
11070 hanging_non_alternate_protocol_socket.set_connect_data(
11071 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711072 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511073 &hanging_non_alternate_protocol_socket);
11074
[email protected]49639fa2011-12-20 23:22:4111075 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111076
mmenkee65e7af2015-10-13 17:16:4211077 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611078 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111080
[email protected]49639fa2011-12-20 23:22:4111081 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1111082 EXPECT_EQ(ERR_IO_PENDING, rv);
11083 EXPECT_EQ(OK, callback.WaitForResult());
11084
11085 const HttpResponseInfo* response = trans->GetResponseInfo();
11086 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011087 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1111088 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311089 EXPECT_FALSE(response->was_fetched_via_spdy);
11090 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1111091
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]631f1322010-04-30 17:59:1111097
[email protected]49639fa2011-12-20 23:22:4111098 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1111099 EXPECT_EQ(ERR_IO_PENDING, rv);
11100 EXPECT_EQ(OK, callback.WaitForResult());
11101
11102 response = trans->GetResponseInfo();
11103 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011104 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0211105 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311106 EXPECT_TRUE(response->was_fetched_via_spdy);
11107 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1111108
11109 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11110 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1311111 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2311112 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311113 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311114 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311115 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111116
[email protected]029c83b62013-01-24 05:28:2011117 LoadTimingInfo load_timing_info;
11118 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11119 TestLoadTimingNotReusedWithPac(load_timing_info,
11120 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111121}
[email protected]631f1322010-04-30 17:59:1111122
[email protected]23e482282013-06-14 16:08:0211123TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:5411124 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
rch3f4b8452016-02-23 16:59:3211125 session_deps_.parse_alternative_services = false;
bncf33fb31b2016-01-29 15:22:2611126 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2ff8b312010-04-26 22:20:5411127
11128 HttpRequestInfo request;
11129 request.method = "GET";
bncce36dca22015-04-21 22:11:2311130 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411131 request.load_flags = 0;
11132
[email protected]8a0fc822013-06-27 20:52:4311133 std::string alternate_protocol_http_header =
11134 GetAlternateProtocolHttpHeader();
11135
[email protected]2ff8b312010-04-26 22:20:5411136 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211137 MockRead("HTTP/1.1 200 OK\r\n"),
11138 MockRead(alternate_protocol_http_header.c_str()),
11139 MockRead("\r\n"),
11140 MockRead("hello world"),
11141 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411142 };
11143
11144 StaticSocketDataProvider first_transaction(
11145 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711146 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5411147
[email protected]8ddf8322012-02-23 18:08:0611148 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811149 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2311150 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11151 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0711152 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5411153
bncb03b1092016-04-06 11:19:5511154 scoped_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911155 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1311156 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411157
bncb03b1092016-04-06 11:19:5511158 scoped_ptr<SpdySerializedFrame> resp(
11159 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11160 scoped_ptr<SpdySerializedFrame> data(
11161 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411162 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311163 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411164 };
11165
rch8e6c6c42015-05-01 14:05:1311166 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11167 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711168 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411169
[email protected]83039bb2011-12-09 18:43:5511170 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411171
mmenkee65e7af2015-10-13 17:16:4211172 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411173
[email protected]262eec82013-03-19 21:01:3611174 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011175 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411176
[email protected]49639fa2011-12-20 23:22:4111177 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5411178 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111179 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5411180
11181 const HttpResponseInfo* response = trans->GetResponseInfo();
11182 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011183 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5411184 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11185
11186 std::string response_data;
11187 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11188 EXPECT_EQ("hello world", response_data);
11189
11190 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2311191 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011192 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311193 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711194 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4211195 CreateSecureSpdySession(session.get(), key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3811196
[email protected]90499482013-06-01 00:39:5011197 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411198
[email protected]49639fa2011-12-20 23:22:4111199 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5411200 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111201 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5411202
11203 response = trans->GetResponseInfo();
11204 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011205 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0211206 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311207 EXPECT_TRUE(response->was_fetched_via_spdy);
11208 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411209
11210 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11211 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211212}
11213
[email protected]044de0642010-06-17 10:42:1511214// GenerateAuthToken is a mighty big test.
11215// It tests all permutation of GenerateAuthToken behavior:
11216// - Synchronous and Asynchronous completion.
11217// - OK or error on completion.
11218// - Direct connection, non-authenticating proxy, and authenticating proxy.
11219// - HTTP or HTTPS backend (to include proxy tunneling).
11220// - Non-authenticating and authenticating backend.
11221//
[email protected]fe3b7dc2012-02-03 19:52:0911222// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511223// problems generating an auth token for an authenticating proxy, we don't
11224// need to test all permutations of the backend server).
11225//
11226// The test proceeds by going over each of the configuration cases, and
11227// potentially running up to three rounds in each of the tests. The TestConfig
11228// specifies both the configuration for the test as well as the expectations
11229// for the results.
[email protected]23e482282013-06-14 16:08:0211230TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011231 static const char kServer[] = "http://www.example.com";
11232 static const char kSecureServer[] = "https://www.example.com";
11233 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511234 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
11235
11236 enum AuthTiming {
11237 AUTH_NONE,
11238 AUTH_SYNC,
11239 AUTH_ASYNC,
11240 };
11241
11242 const MockWrite kGet(
11243 "GET / HTTP/1.1\r\n"
11244 "Host: www.example.com\r\n"
11245 "Connection: keep-alive\r\n\r\n");
11246 const MockWrite kGetProxy(
11247 "GET http://www.example.com/ HTTP/1.1\r\n"
11248 "Host: www.example.com\r\n"
11249 "Proxy-Connection: keep-alive\r\n\r\n");
11250 const MockWrite kGetAuth(
11251 "GET / HTTP/1.1\r\n"
11252 "Host: www.example.com\r\n"
11253 "Connection: keep-alive\r\n"
11254 "Authorization: auth_token\r\n\r\n");
11255 const MockWrite kGetProxyAuth(
11256 "GET http://www.example.com/ HTTP/1.1\r\n"
11257 "Host: www.example.com\r\n"
11258 "Proxy-Connection: keep-alive\r\n"
11259 "Proxy-Authorization: auth_token\r\n\r\n");
11260 const MockWrite kGetAuthThroughProxy(
11261 "GET http://www.example.com/ HTTP/1.1\r\n"
11262 "Host: www.example.com\r\n"
11263 "Proxy-Connection: keep-alive\r\n"
11264 "Authorization: auth_token\r\n\r\n");
11265 const MockWrite kGetAuthWithProxyAuth(
11266 "GET http://www.example.com/ HTTP/1.1\r\n"
11267 "Host: www.example.com\r\n"
11268 "Proxy-Connection: keep-alive\r\n"
11269 "Proxy-Authorization: auth_token\r\n"
11270 "Authorization: auth_token\r\n\r\n");
11271 const MockWrite kConnect(
11272 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711273 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511274 "Proxy-Connection: keep-alive\r\n\r\n");
11275 const MockWrite kConnectProxyAuth(
11276 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711277 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511278 "Proxy-Connection: keep-alive\r\n"
11279 "Proxy-Authorization: auth_token\r\n\r\n");
11280
11281 const MockRead kSuccess(
11282 "HTTP/1.1 200 OK\r\n"
11283 "Content-Type: text/html; charset=iso-8859-1\r\n"
11284 "Content-Length: 3\r\n\r\n"
11285 "Yes");
11286 const MockRead kFailure(
11287 "Should not be called.");
11288 const MockRead kServerChallenge(
11289 "HTTP/1.1 401 Unauthorized\r\n"
11290 "WWW-Authenticate: Mock realm=server\r\n"
11291 "Content-Type: text/html; charset=iso-8859-1\r\n"
11292 "Content-Length: 14\r\n\r\n"
11293 "Unauthorized\r\n");
11294 const MockRead kProxyChallenge(
11295 "HTTP/1.1 407 Unauthorized\r\n"
11296 "Proxy-Authenticate: Mock realm=proxy\r\n"
11297 "Proxy-Connection: close\r\n"
11298 "Content-Type: text/html; charset=iso-8859-1\r\n"
11299 "Content-Length: 14\r\n\r\n"
11300 "Unauthorized\r\n");
11301 const MockRead kProxyConnected(
11302 "HTTP/1.1 200 Connection Established\r\n\r\n");
11303
11304 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11305 // no constructors, but the C++ compiler on Windows warns about
11306 // unspecified data in compound literals. So, moved to using constructors,
11307 // and TestRound's created with the default constructor should not be used.
11308 struct TestRound {
11309 TestRound()
11310 : expected_rv(ERR_UNEXPECTED),
11311 extra_write(NULL),
11312 extra_read(NULL) {
11313 }
11314 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11315 int expected_rv_arg)
11316 : write(write_arg),
11317 read(read_arg),
11318 expected_rv(expected_rv_arg),
11319 extra_write(NULL),
11320 extra_read(NULL) {
11321 }
11322 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11323 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111324 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511325 : write(write_arg),
11326 read(read_arg),
11327 expected_rv(expected_rv_arg),
11328 extra_write(extra_write_arg),
11329 extra_read(extra_read_arg) {
11330 }
11331 MockWrite write;
11332 MockRead read;
11333 int expected_rv;
11334 const MockWrite* extra_write;
11335 const MockRead* extra_read;
11336 };
11337
11338 static const int kNoSSL = 500;
11339
11340 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5111341 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511342 AuthTiming proxy_auth_timing;
11343 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5111344 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511345 AuthTiming server_auth_timing;
11346 int server_auth_rv;
11347 int num_auth_rounds;
11348 int first_ssl_round;
11349 TestRound rounds[3];
11350 } test_configs[] = {
11351 // Non-authenticating HTTP server with a direct connection.
11352 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11353 { TestRound(kGet, kSuccess, OK)}},
11354 // Authenticating HTTP server with a direct connection.
11355 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11356 { TestRound(kGet, kServerChallenge, OK),
11357 TestRound(kGetAuth, kSuccess, OK)}},
11358 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11359 { TestRound(kGet, kServerChallenge, OK),
11360 TestRound(kGetAuth, kFailure, kAuthErr)}},
11361 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11362 { TestRound(kGet, kServerChallenge, OK),
11363 TestRound(kGetAuth, kSuccess, OK)}},
11364 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11365 { TestRound(kGet, kServerChallenge, OK),
11366 TestRound(kGetAuth, kFailure, kAuthErr)}},
11367 // Non-authenticating HTTP server through a non-authenticating proxy.
11368 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11369 { TestRound(kGetProxy, kSuccess, OK)}},
11370 // Authenticating HTTP server through a non-authenticating proxy.
11371 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11372 { TestRound(kGetProxy, kServerChallenge, OK),
11373 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11374 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11375 { TestRound(kGetProxy, kServerChallenge, OK),
11376 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11377 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11378 { TestRound(kGetProxy, kServerChallenge, OK),
11379 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11380 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11381 { TestRound(kGetProxy, kServerChallenge, OK),
11382 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11383 // Non-authenticating HTTP server through an authenticating proxy.
11384 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11385 { TestRound(kGetProxy, kProxyChallenge, OK),
11386 TestRound(kGetProxyAuth, kSuccess, OK)}},
11387 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11388 { TestRound(kGetProxy, kProxyChallenge, OK),
11389 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11390 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11391 { TestRound(kGetProxy, kProxyChallenge, OK),
11392 TestRound(kGetProxyAuth, kSuccess, OK)}},
11393 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11394 { TestRound(kGetProxy, kProxyChallenge, OK),
11395 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11396 // Authenticating HTTP server through an authenticating proxy.
11397 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11398 { TestRound(kGetProxy, kProxyChallenge, OK),
11399 TestRound(kGetProxyAuth, kServerChallenge, OK),
11400 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11401 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11402 { TestRound(kGetProxy, kProxyChallenge, OK),
11403 TestRound(kGetProxyAuth, kServerChallenge, OK),
11404 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11405 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11406 { TestRound(kGetProxy, kProxyChallenge, OK),
11407 TestRound(kGetProxyAuth, kServerChallenge, OK),
11408 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11409 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11410 { TestRound(kGetProxy, kProxyChallenge, OK),
11411 TestRound(kGetProxyAuth, kServerChallenge, OK),
11412 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11413 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11414 { TestRound(kGetProxy, kProxyChallenge, OK),
11415 TestRound(kGetProxyAuth, kServerChallenge, OK),
11416 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11417 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11418 { TestRound(kGetProxy, kProxyChallenge, OK),
11419 TestRound(kGetProxyAuth, kServerChallenge, OK),
11420 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11421 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11422 { TestRound(kGetProxy, kProxyChallenge, OK),
11423 TestRound(kGetProxyAuth, kServerChallenge, OK),
11424 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11425 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11426 { TestRound(kGetProxy, kProxyChallenge, OK),
11427 TestRound(kGetProxyAuth, kServerChallenge, OK),
11428 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11429 // Non-authenticating HTTPS server with a direct connection.
11430 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11431 { TestRound(kGet, kSuccess, OK)}},
11432 // Authenticating HTTPS server with a direct connection.
11433 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11434 { TestRound(kGet, kServerChallenge, OK),
11435 TestRound(kGetAuth, kSuccess, OK)}},
11436 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11437 { TestRound(kGet, kServerChallenge, OK),
11438 TestRound(kGetAuth, kFailure, kAuthErr)}},
11439 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11440 { TestRound(kGet, kServerChallenge, OK),
11441 TestRound(kGetAuth, kSuccess, OK)}},
11442 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11443 { TestRound(kGet, kServerChallenge, OK),
11444 TestRound(kGetAuth, kFailure, kAuthErr)}},
11445 // Non-authenticating HTTPS server with a non-authenticating proxy.
11446 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11447 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11448 // Authenticating HTTPS server through a non-authenticating proxy.
11449 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11450 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11451 TestRound(kGetAuth, kSuccess, OK)}},
11452 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11453 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11454 TestRound(kGetAuth, kFailure, kAuthErr)}},
11455 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11456 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11457 TestRound(kGetAuth, kSuccess, OK)}},
11458 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11459 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11460 TestRound(kGetAuth, kFailure, kAuthErr)}},
11461 // Non-Authenticating HTTPS server through an authenticating proxy.
11462 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11463 { TestRound(kConnect, kProxyChallenge, OK),
11464 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11465 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11466 { TestRound(kConnect, kProxyChallenge, OK),
11467 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11468 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11469 { TestRound(kConnect, kProxyChallenge, OK),
11470 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11471 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11472 { TestRound(kConnect, kProxyChallenge, OK),
11473 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11474 // Authenticating HTTPS server through an authenticating proxy.
11475 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11476 { TestRound(kConnect, kProxyChallenge, OK),
11477 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11478 &kGet, &kServerChallenge),
11479 TestRound(kGetAuth, kSuccess, OK)}},
11480 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11481 { TestRound(kConnect, kProxyChallenge, OK),
11482 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11483 &kGet, &kServerChallenge),
11484 TestRound(kGetAuth, kFailure, kAuthErr)}},
11485 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11486 { TestRound(kConnect, kProxyChallenge, OK),
11487 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11488 &kGet, &kServerChallenge),
11489 TestRound(kGetAuth, kSuccess, OK)}},
11490 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11491 { TestRound(kConnect, kProxyChallenge, OK),
11492 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11493 &kGet, &kServerChallenge),
11494 TestRound(kGetAuth, kFailure, kAuthErr)}},
11495 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11496 { TestRound(kConnect, kProxyChallenge, OK),
11497 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11498 &kGet, &kServerChallenge),
11499 TestRound(kGetAuth, kSuccess, OK)}},
11500 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11501 { TestRound(kConnect, kProxyChallenge, OK),
11502 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11503 &kGet, &kServerChallenge),
11504 TestRound(kGetAuth, kFailure, kAuthErr)}},
11505 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11506 { TestRound(kConnect, kProxyChallenge, OK),
11507 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11508 &kGet, &kServerChallenge),
11509 TestRound(kGetAuth, kSuccess, OK)}},
11510 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11511 { TestRound(kConnect, kProxyChallenge, OK),
11512 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11513 &kGet, &kServerChallenge),
11514 TestRound(kGetAuth, kFailure, kAuthErr)}},
11515 };
11516
viettrungluue4a8b882014-10-16 06:17:3811517 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0811518 HttpAuthHandlerMock::Factory* auth_factory(
11519 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711520 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4911521 SSLInfo empty_ssl_info;
[email protected]044de0642010-06-17 10:42:1511522 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2611523
11524 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1511525 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0811526 for (int n = 0; n < 2; n++) {
11527 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11528 std::string auth_challenge = "Mock realm=proxy";
11529 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2411530 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11531 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0811532 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
asanka5ffd5d72016-03-23 16:20:4911533 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811534 auth_handler->SetGenerateExpectation(
11535 test_config.proxy_auth_timing == AUTH_ASYNC,
11536 test_config.proxy_auth_rv);
11537 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11538 }
[email protected]044de0642010-06-17 10:42:1511539 }
11540 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0011541 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1511542 std::string auth_challenge = "Mock realm=server";
11543 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2411544 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11545 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1511546 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911547 empty_ssl_info, origin, BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511548 auth_handler->SetGenerateExpectation(
11549 test_config.server_auth_timing == AUTH_ASYNC,
11550 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0811551 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1511552 }
11553 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0311554 session_deps_.proxy_service =
11555 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1511556 } else {
rdsmith82957ad2015-09-16 19:42:0311557 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1511558 }
11559
11560 HttpRequestInfo request;
11561 request.method = "GET";
11562 request.url = GURL(test_config.server_url);
11563 request.load_flags = 0;
11564
mmenkee65e7af2015-10-13 17:16:4211565 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1511566
rchcb68dc62015-05-21 04:45:3611567 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
11568
11569 std::vector<std::vector<MockRead>> mock_reads(1);
11570 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1511571 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11572 const TestRound& read_write_round = test_config.rounds[round];
11573
11574 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3611575 mock_reads.back().push_back(read_write_round.read);
11576 mock_writes.back().push_back(read_write_round.write);
11577
11578 // kProxyChallenge uses Proxy-Connection: close which means that the
11579 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5411580 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3611581 mock_reads.push_back(std::vector<MockRead>());
11582 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1511583 }
11584
rchcb68dc62015-05-21 04:45:3611585 if (read_write_round.extra_read) {
11586 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1511587 }
rchcb68dc62015-05-21 04:45:3611588 if (read_write_round.extra_write) {
11589 mock_writes.back().push_back(*read_write_round.extra_write);
11590 }
[email protected]044de0642010-06-17 10:42:1511591
11592 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1511593 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0711594 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1511595 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3611596 }
[email protected]044de0642010-06-17 10:42:1511597
olli.raula525048c2015-12-10 07:38:3211598 std::vector<scoped_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3611599 for (size_t i = 0; i < mock_reads.size(); ++i) {
olli.raula525048c2015-12-10 07:38:3211600 data_providers.push_back(make_scoped_ptr(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5411601 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3211602 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3611603 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3211604 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3611605 }
11606
mmenkecc2298e2015-12-07 18:20:1811607 // Transaction must be created after DataProviders, so it's destroyed before
11608 // they are as well.
11609 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11610
rchcb68dc62015-05-21 04:45:3611611 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11612 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1511613 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4111614 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1511615 int rv;
11616 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4111617 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511618 } else {
[email protected]49639fa2011-12-20 23:22:4111619 rv = trans.RestartWithAuth(
11620 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1511621 }
11622 if (rv == ERR_IO_PENDING)
11623 rv = callback.WaitForResult();
11624
11625 // Compare results with expected data.
11626 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5011627 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5511628 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1511629 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
11630 continue;
11631 }
11632 if (round + 1 < test_config.num_auth_rounds) {
11633 EXPECT_FALSE(response->auth_challenge.get() == NULL);
11634 } else {
11635 EXPECT_TRUE(response->auth_challenge.get() == NULL);
11636 }
11637 }
[email protected]e5ae96a2010-04-14 20:12:4511638 }
11639}
11640
[email protected]23e482282013-06-14 16:08:0211641TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1411642 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1411643 HttpAuthHandlerMock::Factory* auth_factory(
11644 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711645 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0311646 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0711647 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
11648 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1411649
11650 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11651 auth_handler->set_connection_based(true);
11652 std::string auth_challenge = "Mock realm=server";
11653 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2411654 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11655 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4911656 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1411657 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911658 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811659 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1411660
[email protected]c871bce92010-07-15 21:51:1411661 int rv = OK;
11662 const HttpResponseInfo* response = NULL;
11663 HttpRequestInfo request;
11664 request.method = "GET";
11665 request.url = origin;
11666 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2711667
mmenkee65e7af2015-10-13 17:16:4211668 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1011669
11670 // Use a TCP Socket Pool with only one connection per group. This is used
11671 // to validate that the TCP socket is not released to the pool between
11672 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4211673 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2811674 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1011675 50, // Max sockets for pool
11676 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0711677 session_deps_.host_resolver.get(),
11678 session_deps_.socket_factory.get(),
11679 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4411680 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
11681 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0211682 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4811683 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1011684
[email protected]262eec82013-03-19 21:01:3611685 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011686 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111687 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1411688
11689 const MockWrite kGet(
11690 "GET / HTTP/1.1\r\n"
11691 "Host: www.example.com\r\n"
11692 "Connection: keep-alive\r\n\r\n");
11693 const MockWrite kGetAuth(
11694 "GET / HTTP/1.1\r\n"
11695 "Host: www.example.com\r\n"
11696 "Connection: keep-alive\r\n"
11697 "Authorization: auth_token\r\n\r\n");
11698
11699 const MockRead kServerChallenge(
11700 "HTTP/1.1 401 Unauthorized\r\n"
11701 "WWW-Authenticate: Mock realm=server\r\n"
11702 "Content-Type: text/html; charset=iso-8859-1\r\n"
11703 "Content-Length: 14\r\n\r\n"
11704 "Unauthorized\r\n");
11705 const MockRead kSuccess(
11706 "HTTP/1.1 200 OK\r\n"
11707 "Content-Type: text/html; charset=iso-8859-1\r\n"
11708 "Content-Length: 3\r\n\r\n"
11709 "Yes");
11710
11711 MockWrite writes[] = {
11712 // First round
11713 kGet,
11714 // Second round
11715 kGetAuth,
11716 // Third round
11717 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3011718 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1011719 kGetAuth,
11720 // Competing request
11721 kGet,
[email protected]c871bce92010-07-15 21:51:1411722 };
11723 MockRead reads[] = {
11724 // First round
11725 kServerChallenge,
11726 // Second round
11727 kServerChallenge,
11728 // Third round
[email protected]eca50e122010-09-11 14:03:3011729 kServerChallenge,
11730 // Fourth round
[email protected]c871bce92010-07-15 21:51:1411731 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1011732 // Competing response
11733 kSuccess,
[email protected]c871bce92010-07-15 21:51:1411734 };
11735 StaticSocketDataProvider data_provider(reads, arraysize(reads),
11736 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0711737 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1411738
thestig9d3bb0c2015-01-24 00:49:5111739 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1011740
11741 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1411742 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111743 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1411744 if (rv == ERR_IO_PENDING)
11745 rv = callback.WaitForResult();
11746 EXPECT_EQ(OK, rv);
11747 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011748 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411749 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811750 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411751
[email protected]7ef4cbbb2011-02-06 11:19:1011752 // In between rounds, another request comes in for the same domain.
11753 // It should not be able to grab the TCP socket that trans has already
11754 // claimed.
11755 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5011756 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111757 TestCompletionCallback callback_compete;
11758 rv = trans_compete->Start(
11759 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1011760 EXPECT_EQ(ERR_IO_PENDING, rv);
11761 // callback_compete.WaitForResult at this point would stall forever,
11762 // since the HttpNetworkTransaction does not release the request back to
11763 // the pool until after authentication completes.
11764
11765 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1411766 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111767 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411768 if (rv == ERR_IO_PENDING)
11769 rv = callback.WaitForResult();
11770 EXPECT_EQ(OK, rv);
11771 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011772 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411773 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811774 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411775
[email protected]7ef4cbbb2011-02-06 11:19:1011776 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1411777 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111778 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411779 if (rv == ERR_IO_PENDING)
11780 rv = callback.WaitForResult();
11781 EXPECT_EQ(OK, rv);
11782 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011783 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1411784 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811785 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3011786
[email protected]7ef4cbbb2011-02-06 11:19:1011787 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3011788 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111789 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3011790 if (rv == ERR_IO_PENDING)
11791 rv = callback.WaitForResult();
11792 EXPECT_EQ(OK, rv);
11793 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011794 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3011795 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2811796 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011797
11798 // Read the body since the fourth round was successful. This will also
11799 // release the socket back to the pool.
11800 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5011801 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011802 if (rv == ERR_IO_PENDING)
11803 rv = callback.WaitForResult();
11804 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011805 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011806 EXPECT_EQ(0, rv);
11807 // There are still 0 idle sockets, since the trans_compete transaction
11808 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2811809 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011810
11811 // The competing request can now finish. Wait for the headers and then
11812 // read the body.
11813 rv = callback_compete.WaitForResult();
11814 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5011815 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011816 if (rv == ERR_IO_PENDING)
11817 rv = callback.WaitForResult();
11818 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011819 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011820 EXPECT_EQ(0, rv);
11821
11822 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2811823 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411824}
11825
[email protected]65041fa2010-05-21 06:56:5311826// This tests the case that a request is issued via http instead of spdy after
11827// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0211828TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bncf33fb31b2016-01-29 15:22:2611829 session_deps_.parse_alternative_services = true;
11830 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d7599122014-05-24 03:37:2311831
[email protected]65041fa2010-05-21 06:56:5311832 HttpRequestInfo request;
11833 request.method = "GET";
bncce36dca22015-04-21 22:11:2311834 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5311835 request.load_flags = 0;
11836
11837 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2311838 MockWrite(
11839 "GET / HTTP/1.1\r\n"
11840 "Host: www.example.org\r\n"
11841 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5311842 };
11843
[email protected]8a0fc822013-06-27 20:52:4311844 std::string alternate_protocol_http_header =
11845 GetAlternateProtocolHttpHeader();
11846
[email protected]65041fa2010-05-21 06:56:5311847 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211848 MockRead("HTTP/1.1 200 OK\r\n"),
11849 MockRead(alternate_protocol_http_header.c_str()),
11850 MockRead("\r\n"),
11851 MockRead("hello world"),
11852 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5311853 };
11854
[email protected]8ddf8322012-02-23 18:08:0611855 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4811856 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5311857
[email protected]bb88e1d32013-05-03 23:11:0711858 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5311859
11860 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
11861 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711862 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5311863
[email protected]49639fa2011-12-20 23:22:4111864 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5311865
mmenkee65e7af2015-10-13 17:16:4211866 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611867 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5311869
[email protected]49639fa2011-12-20 23:22:4111870 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5311871
11872 EXPECT_EQ(ERR_IO_PENDING, rv);
11873 EXPECT_EQ(OK, callback.WaitForResult());
11874
11875 const HttpResponseInfo* response = trans->GetResponseInfo();
11876 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011877 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5311878 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11879
11880 std::string response_data;
11881 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11882 EXPECT_EQ("hello world", response_data);
11883
11884 EXPECT_FALSE(response->was_fetched_via_spdy);
11885 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5311886}
[email protected]26ef6582010-06-24 02:30:4711887
bnc55ff9da2015-08-19 18:42:3511888// Simulate the SSL handshake completing with an NPN negotiation followed by an
11889// immediate server closing of the socket.
11890// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0211891TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bncf33fb31b2016-01-29 15:22:2611892 session_deps_.parse_alternative_services = true;
11893 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]26ef6582010-06-24 02:30:4711894
11895 HttpRequestInfo request;
11896 request.method = "GET";
bncce36dca22015-04-21 22:11:2311897 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4711898 request.load_flags = 0;
11899
[email protected]8ddf8322012-02-23 18:08:0611900 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811901 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0711902 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4711903
bncb03b1092016-04-06 11:19:5511904 scoped_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911905 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1311906 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4711907
11908 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611909 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4711910 };
11911
rch8e6c6c42015-05-01 14:05:1311912 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11913 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711914 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4711915
[email protected]49639fa2011-12-20 23:22:4111916 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4711917
mmenkee65e7af2015-10-13 17:16:4211918 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611919 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011920 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4711921
[email protected]49639fa2011-12-20 23:22:4111922 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4711923 EXPECT_EQ(ERR_IO_PENDING, rv);
11924 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4711925}
[email protected]65d34382010-07-01 18:12:2611926
[email protected]795cbf82013-07-22 09:37:2711927// A subclass of HttpAuthHandlerMock that records the request URL when
11928// it gets it. This is needed since the auth handler may get destroyed
11929// before we get a chance to query it.
11930class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
11931 public:
11932 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
11933
dchengb03027d2014-10-21 12:00:2011934 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2711935
11936 protected:
dchengb03027d2014-10-21 12:00:2011937 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
11938 const HttpRequestInfo* request,
11939 const CompletionCallback& callback,
11940 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2711941 *url_ = request->url;
11942 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
11943 credentials, request, callback, auth_token);
11944 }
11945
11946 private:
11947 GURL* url_;
11948};
11949
bnc55ff9da2015-08-19 18:42:3511950// This test ensures that the URL passed into the proxy is upgraded to https
11951// when doing an Alternate Protocol upgrade.
[email protected]23e482282013-06-14 16:08:0211952TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
rch3f4b8452016-02-23 16:59:3211953 session_deps_.parse_alternative_services = false;
bncf33fb31b2016-01-29 15:22:2611954 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]f45c1ee2010-08-03 00:54:3011955
rdsmith82957ad2015-09-16 19:42:0311956 session_deps_.proxy_service =
11957 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5111958 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711959 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2711960 GURL request_url;
11961 {
11962 HttpAuthHandlerMock::Factory* auth_factory =
11963 new HttpAuthHandlerMock::Factory();
11964 UrlRecordingHttpAuthHandlerMock* auth_handler =
11965 new UrlRecordingHttpAuthHandlerMock(&request_url);
11966 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11967 auth_factory->set_do_init_from_challenge(true);
11968 session_deps_.http_auth_handler_factory.reset(auth_factory);
11969 }
[email protected]f45c1ee2010-08-03 00:54:3011970
11971 HttpRequestInfo request;
11972 request.method = "GET";
bncce36dca22015-04-21 22:11:2311973 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3011974 request.load_flags = 0;
11975
11976 // First round goes unauthenticated through the proxy.
11977 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2311978 MockWrite(
11979 "GET http://www.example.org/ HTTP/1.1\r\n"
11980 "Host: www.example.org\r\n"
11981 "Proxy-Connection: keep-alive\r\n"
11982 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011983 };
11984 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0611985 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3811986 MockRead("HTTP/1.1 200 OK\r\n"),
11987 MockRead("Alternate-Protocol: 443:"),
11988 MockRead(GetAlternateProtocolFromParam()),
11989 MockRead("\r\n"),
11990 MockRead("Proxy-Connection: close\r\n"),
11991 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3011992 };
11993 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
11994 data_writes_1, arraysize(data_writes_1));
11995
bncce36dca22015-04-21 22:11:2311996 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3011997 // Alternate-Protocol announcement in the first round. It fails due
11998 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2311999 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5912000 // Proxy-Authorization headers. There is then a SPDY request round.
12001 //
[email protected]fe3b7dc2012-02-03 19:52:0912002 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
12003 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
12004 // does a Disconnect and Connect on the same socket, rather than trying
12005 // to obtain a new one.
12006 //
[email protected]394816e92010-08-03 07:38:5912007 // NOTE: Originally, the proxy response to the second CONNECT request
12008 // simply returned another 407 so the unit test could skip the SSL connection
12009 // establishment and SPDY framing issues. Alas, the
12010 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3012011 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5912012
bncb03b1092016-04-06 11:19:5512013 scoped_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912014 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
bncb03b1092016-04-06 11:19:5512015 scoped_ptr<SpdySerializedFrame> resp(
12016 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12017 scoped_ptr<SpdySerializedFrame> data(
12018 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3012019
[email protected]394816e92010-08-03 07:38:5912020 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2312021 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1312022 MockWrite(ASYNC, 0,
12023 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712024 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312025 "Proxy-Connection: keep-alive\r\n"
12026 "\r\n"),
[email protected]394816e92010-08-03 07:38:5912027
bncce36dca22015-04-21 22:11:2312028 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1312029 MockWrite(ASYNC, 2,
12030 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712031 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312032 "Proxy-Connection: keep-alive\r\n"
12033 "Proxy-Authorization: auth_token\r\n"
12034 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3012035
bncce36dca22015-04-21 22:11:2312036 // SPDY request
rch8e6c6c42015-05-01 14:05:1312037 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3012038 };
[email protected]394816e92010-08-03 07:38:5912039 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1312040 // First connection attempt fails
mmenkee71e15332015-10-07 16:39:5412041 MockRead(ASYNC, 1,
12042 "HTTP/1.1 407 Unauthorized\r\n"
12043 "Proxy-Authenticate: Mock\r\n"
12044 "Content-Length: 0\r\n"
12045 "Proxy-Connection: keep-alive\r\n"
12046 "\r\n"),
[email protected]394816e92010-08-03 07:38:5912047
rch8e6c6c42015-05-01 14:05:1312048 // Second connection attempt passes
mmenkee71e15332015-10-07 16:39:5412049 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5912050
rch8e6c6c42015-05-01 14:05:1312051 // SPDY response
mmenkee71e15332015-10-07 16:39:5412052 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1312053 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5912054 };
rch8e6c6c42015-05-01 14:05:1312055 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
12056 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3012057
[email protected]8ddf8322012-02-23 18:08:0612058 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812059 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2312060 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
12061 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3012062
[email protected]d973e99a2012-02-17 21:02:3612063 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512064 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12065 NULL, 0, NULL, 0);
12066 hanging_non_alternate_protocol_socket.set_connect_data(
12067 never_finishing_connect);
12068
[email protected]bb88e1d32013-05-03 23:11:0712069 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
12070 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
12071 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12072 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512073 &hanging_non_alternate_protocol_socket);
mmenkee65e7af2015-10-13 17:16:4212074 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3012075
12076 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4112077 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3612078 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5012079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4112080 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3012081 EXPECT_EQ(ERR_IO_PENDING, rv);
12082 EXPECT_EQ(OK, callback_1.WaitForResult());
12083
12084 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4112085 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3612086 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5012087 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4112088 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3012089 EXPECT_EQ(ERR_IO_PENDING, rv);
12090 EXPECT_EQ(OK, callback_2.WaitForResult());
12091 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5012092 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3012093 ASSERT_FALSE(response->auth_challenge.get() == NULL);
12094
12095 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4112096 TestCompletionCallback callback_3;
12097 rv = trans_2->RestartWithAuth(
12098 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3012099 EXPECT_EQ(ERR_IO_PENDING, rv);
12100 EXPECT_EQ(OK, callback_3.WaitForResult());
12101
12102 // After all that work, these two lines (or actually, just the scheme) are
12103 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3012104 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2312105 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3012106
[email protected]029c83b62013-01-24 05:28:2012107 LoadTimingInfo load_timing_info;
12108 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
12109 TestLoadTimingNotReusedWithPac(load_timing_info,
12110 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3812111}
12112
12113// Test that if we cancel the transaction as the connection is completing, that
12114// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0212115TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812116 // Setup everything about the connection to complete synchronously, so that
12117 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12118 // for is the callback from the HttpStreamRequest.
12119 // Then cancel the transaction.
12120 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612121 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812122 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612123 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12124 MockRead(SYNCHRONOUS, "hello world"),
12125 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812126 };
12127
[email protected]8e6441ca2010-08-19 05:56:3812128 HttpRequestInfo request;
12129 request.method = "GET";
bncce36dca22015-04-21 22:11:2312130 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812131 request.load_flags = 0;
12132
[email protected]bb88e1d32013-05-03 23:11:0712133 session_deps_.host_resolver->set_synchronous_mode(true);
mmenkee65e7af2015-10-13 17:16:4212134 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2712135 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112136 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2712137
[email protected]8e6441ca2010-08-19 05:56:3812138 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12139 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712140 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812141
[email protected]49639fa2011-12-20 23:22:4112142 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812143
vishal.b62985ca92015-04-17 08:45:5112144 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112145 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3812146 EXPECT_EQ(ERR_IO_PENDING, rv);
12147 trans.reset(); // Cancel the transaction here.
12148
[email protected]2da659e2013-05-23 20:51:3412149 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012150}
12151
[email protected]ecab6e052014-05-16 14:58:1212152// Test that if a transaction is cancelled after receiving the headers, the
12153// stream is drained properly and added back to the socket pool. The main
12154// purpose of this test is to make sure that an HttpStreamParser can be read
12155// from after the HttpNetworkTransaction and the objects it owns have been
12156// deleted.
12157// See http://crbug.com/368418
12158TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
12159 MockRead data_reads[] = {
12160 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12161 MockRead(ASYNC, "Content-Length: 2\r\n"),
12162 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12163 MockRead(ASYNC, "1"),
12164 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12165 // HttpNetworkTransaction has been deleted.
12166 MockRead(ASYNC, "2"),
12167 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12168 };
12169 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12170 session_deps_.socket_factory->AddSocketDataProvider(&data);
12171
mmenkee65e7af2015-10-13 17:16:4212172 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212173
12174 {
12175 HttpRequestInfo request;
12176 request.method = "GET";
bncce36dca22015-04-21 22:11:2312177 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212178 request.load_flags = 0;
12179
dcheng48459ac22014-08-26 00:46:4112180 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212181 TestCompletionCallback callback;
12182
12183 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
12184 EXPECT_EQ(ERR_IO_PENDING, rv);
12185 callback.WaitForResult();
12186
12187 const HttpResponseInfo* response = trans.GetResponseInfo();
12188 ASSERT_TRUE(response != NULL);
12189 EXPECT_TRUE(response->headers.get() != NULL);
12190 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12191
12192 // The transaction and HttpRequestInfo are deleted.
12193 }
12194
12195 // Let the HttpResponseBodyDrainer drain the socket.
12196 base::MessageLoop::current()->RunUntilIdle();
12197
12198 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112199 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212200}
12201
[email protected]76a505b2010-08-25 06:23:0012202// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0212203TEST_P(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312204 session_deps_.proxy_service =
12205 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112206 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712207 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4212208 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012209
[email protected]76a505b2010-08-25 06:23:0012210 HttpRequestInfo request;
12211 request.method = "GET";
bncce36dca22015-04-21 22:11:2312212 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012213
12214 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312215 MockWrite(
12216 "GET http://www.example.org/ HTTP/1.1\r\n"
12217 "Host: www.example.org\r\n"
12218 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012219 };
12220
12221 MockRead data_reads1[] = {
12222 MockRead("HTTP/1.1 200 OK\r\n"),
12223 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12224 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612225 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012226 };
12227
12228 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12229 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712230 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012231
[email protected]49639fa2011-12-20 23:22:4112232 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012233
[email protected]262eec82013-03-19 21:01:3612234 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012235 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2712236 BeforeProxyHeadersSentHandler proxy_headers_handler;
12237 trans->SetBeforeProxyHeadersSentCallback(
12238 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
12239 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012240
[email protected]49639fa2011-12-20 23:22:4112241 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012242 EXPECT_EQ(ERR_IO_PENDING, rv);
12243
12244 rv = callback1.WaitForResult();
12245 EXPECT_EQ(OK, rv);
12246
12247 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5012248 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0012249
12250 EXPECT_TRUE(response->headers->IsKeepAlive());
12251 EXPECT_EQ(200, response->headers->response_code());
12252 EXPECT_EQ(100, response->headers->GetContentLength());
12253 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512254 EXPECT_TRUE(
12255 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2712256 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
12257 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012258 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012259
12260 LoadTimingInfo load_timing_info;
12261 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12262 TestLoadTimingNotReusedWithPac(load_timing_info,
12263 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012264}
12265
12266// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0212267TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312268 session_deps_.proxy_service =
12269 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112270 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712271 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4212272 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012273
[email protected]76a505b2010-08-25 06:23:0012274 HttpRequestInfo request;
12275 request.method = "GET";
bncce36dca22015-04-21 22:11:2312276 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012277
12278 // Since we have proxy, should try to establish tunnel.
12279 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712280 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12281 "Host: www.example.org:443\r\n"
12282 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012283
rsleevidb16bb02015-11-12 23:47:1712284 MockWrite("GET / HTTP/1.1\r\n"
12285 "Host: www.example.org\r\n"
12286 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012287 };
12288
12289 MockRead data_reads1[] = {
12290 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12291
12292 MockRead("HTTP/1.1 200 OK\r\n"),
12293 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12294 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612295 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012296 };
12297
12298 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12299 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712300 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612301 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712302 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012303
[email protected]49639fa2011-12-20 23:22:4112304 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012305
[email protected]262eec82013-03-19 21:01:3612306 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5012308
[email protected]49639fa2011-12-20 23:22:4112309 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012310 EXPECT_EQ(ERR_IO_PENDING, rv);
12311
12312 rv = callback1.WaitForResult();
12313 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4612314 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012315 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012316 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012317 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012318 NetLog::PHASE_NONE);
12319 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012320 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012321 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12322 NetLog::PHASE_NONE);
12323
12324 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5012325 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0012326
12327 EXPECT_TRUE(response->headers->IsKeepAlive());
12328 EXPECT_EQ(200, response->headers->response_code());
12329 EXPECT_EQ(100, response->headers->GetContentLength());
12330 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12331 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512332 EXPECT_TRUE(
12333 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2012334
12335 LoadTimingInfo load_timing_info;
12336 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12337 TestLoadTimingNotReusedWithPac(load_timing_info,
12338 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012339}
12340
rsleevidb16bb02015-11-12 23:47:1712341// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12342// literal host.
12343TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
12344 session_deps_.proxy_service =
12345 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12346 BoundTestNetLog log;
12347 session_deps_.net_log = log.bound().net_log();
12348 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12349
12350 HttpRequestInfo request;
12351 request.method = "GET";
12352 request.url = GURL("https://[::1]:443/");
12353
12354 // Since we have proxy, should try to establish tunnel.
12355 MockWrite data_writes1[] = {
12356 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12357 "Host: [::1]:443\r\n"
12358 "Proxy-Connection: keep-alive\r\n\r\n"),
12359
12360 MockWrite("GET / HTTP/1.1\r\n"
12361 "Host: [::1]\r\n"
12362 "Connection: keep-alive\r\n\r\n"),
12363 };
12364
12365 MockRead data_reads1[] = {
12366 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12367
12368 MockRead("HTTP/1.1 200 OK\r\n"),
12369 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12370 MockRead("Content-Length: 100\r\n\r\n"),
12371 MockRead(SYNCHRONOUS, OK),
12372 };
12373
12374 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12375 data_writes1, arraysize(data_writes1));
12376 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12377 SSLSocketDataProvider ssl(ASYNC, OK);
12378 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12379
12380 TestCompletionCallback callback1;
12381
12382 scoped_ptr<HttpTransaction> trans(
12383 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12384
12385 int rv = trans->Start(&request, callback1.callback(), log.bound());
12386 EXPECT_EQ(ERR_IO_PENDING, rv);
12387
12388 rv = callback1.WaitForResult();
12389 EXPECT_EQ(OK, rv);
12390 TestNetLogEntry::List entries;
12391 log.GetEntries(&entries);
12392 size_t pos = ExpectLogContainsSomewhere(
12393 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12394 NetLog::PHASE_NONE);
12395 ExpectLogContainsSomewhere(
12396 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12397 NetLog::PHASE_NONE);
12398
12399 const HttpResponseInfo* response = trans->GetResponseInfo();
12400 ASSERT_TRUE(response != NULL);
12401
12402 EXPECT_TRUE(response->headers->IsKeepAlive());
12403 EXPECT_EQ(200, response->headers->response_code());
12404 EXPECT_EQ(100, response->headers->GetContentLength());
12405 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12406 EXPECT_TRUE(response->was_fetched_via_proxy);
12407 EXPECT_TRUE(
12408 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
12409
12410 LoadTimingInfo load_timing_info;
12411 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12412 TestLoadTimingNotReusedWithPac(load_timing_info,
12413 CONNECT_TIMING_HAS_SSL_TIMES);
12414}
12415
[email protected]76a505b2010-08-25 06:23:0012416// Test a basic HTTPS GET request through a proxy, but the server hangs up
12417// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0212418TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312419 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112420 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712421 session_deps_.net_log = log.bound().net_log();
mmenkee65e7af2015-10-13 17:16:4212422 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012423
[email protected]76a505b2010-08-25 06:23:0012424 HttpRequestInfo request;
12425 request.method = "GET";
bncce36dca22015-04-21 22:11:2312426 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012427
12428 // Since we have proxy, should try to establish tunnel.
12429 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712430 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12431 "Host: www.example.org:443\r\n"
12432 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012433
rsleevidb16bb02015-11-12 23:47:1712434 MockWrite("GET / HTTP/1.1\r\n"
12435 "Host: www.example.org\r\n"
12436 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012437 };
12438
12439 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0612440 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0012441 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612442 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0012443 };
12444
12445 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12446 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712447 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612448 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712449 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012450
[email protected]49639fa2011-12-20 23:22:4112451 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012452
[email protected]262eec82013-03-19 21:01:3612453 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012454 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5012455
[email protected]49639fa2011-12-20 23:22:4112456 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012457 EXPECT_EQ(ERR_IO_PENDING, rv);
12458
12459 rv = callback1.WaitForResult();
12460 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4612461 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012462 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012463 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012464 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012465 NetLog::PHASE_NONE);
12466 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012467 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012468 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12469 NetLog::PHASE_NONE);
12470}
12471
[email protected]749eefa82010-09-13 22:14:0312472// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0212473TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
bncb03b1092016-04-06 11:19:5512474 scoped_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912475 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1312476 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0312477
bncb03b1092016-04-06 11:19:5512478 scoped_ptr<SpdySerializedFrame> resp(
12479 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12480 scoped_ptr<SpdySerializedFrame> data(
12481 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0312482 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312483 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0312484 };
12485
rch8e6c6c42015-05-01 14:05:1312486 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12487 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712488 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0312489
[email protected]8ddf8322012-02-23 18:08:0612490 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812491 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712492 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0312493
mmenkee65e7af2015-10-13 17:16:4212494 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0312495
12496 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2312497 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012498 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312499 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712500 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4212501 CreateInsecureSpdySession(session.get(), key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312502
12503 HttpRequestInfo request;
12504 request.method = "GET";
bncce36dca22015-04-21 22:11:2312505 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0312506 request.load_flags = 0;
12507
12508 // This is the important line that marks this as a preconnect.
12509 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
12510
[email protected]262eec82013-03-19 21:01:3612511 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012512 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0312513
[email protected]41d64e82013-07-03 22:44:2612514 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4112515 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312516 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112517 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0312518}
12519
[email protected]73b8dd222010-11-11 19:55:2412520// Given a net error, cause that error to be returned from the first Write()
12521// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0212522void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0712523 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2912524 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712525 request_info.url = GURL("https://www.example.com/");
12526 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912527 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712528
[email protected]8ddf8322012-02-23 18:08:0612529 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2912530 MockWrite data_writes[] = {
12531 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2412532 };
ttuttle859dc7a2015-04-23 19:42:2912533 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712534 session_deps_.socket_factory->AddSocketDataProvider(&data);
12535 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2412536
mmenkee65e7af2015-10-13 17:16:4212537 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612538 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2412540
[email protected]49639fa2011-12-20 23:22:4112541 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912542 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12543 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2412544 rv = callback.WaitForResult();
12545 ASSERT_EQ(error, rv);
12546}
12547
[email protected]23e482282013-06-14 16:08:0212548TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2412549 // Just check a grab bag of cert errors.
12550 static const int kErrors[] = {
12551 ERR_CERT_COMMON_NAME_INVALID,
12552 ERR_CERT_AUTHORITY_INVALID,
12553 ERR_CERT_DATE_INVALID,
12554 };
12555 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0612556 CheckErrorIsPassedBack(kErrors[i], ASYNC);
12557 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2412558 }
12559}
12560
[email protected]bd0b6772011-01-11 19:59:3012561// Ensure that a client certificate is removed from the SSL client auth
12562// cache when:
12563// 1) No proxy is involved.
12564// 2) TLS False Start is disabled.
12565// 3) The initial TLS handshake requests a client certificate.
12566// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212567TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312568 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912569 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712570 request_info.url = GURL("https://www.example.com/");
12571 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912572 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712573
[email protected]bd0b6772011-01-11 19:59:3012574 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112575 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012576
12577 // [ssl_]data1 contains the data for the first SSL handshake. When a
12578 // CertificateRequest is received for the first time, the handshake will
12579 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2912580 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012581 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712582 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912583 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712584 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012585
12586 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
12587 // False Start is not being used, the result of the SSL handshake will be
12588 // returned as part of the SSLClientSocket::Connect() call. This test
12589 // matches the result of a server sending a handshake_failure alert,
12590 // rather than a Finished message, because it requires a client
12591 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2912592 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012593 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712594 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912595 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712596 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012597
12598 // [ssl_]data3 contains the data for the third SSL handshake. When a
12599 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212600 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
12601 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3012602 // of the HttpNetworkTransaction. Because this test failure is due to
12603 // requiring a client certificate, this fallback handshake should also
12604 // fail.
ttuttle859dc7a2015-04-23 19:42:2912605 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012606 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712607 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912608 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712609 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012610
[email protected]80c75f682012-05-26 16:22:1712611 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
12612 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212613 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
12614 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1712615 // of the HttpNetworkTransaction. Because this test failure is due to
12616 // requiring a client certificate, this fallback handshake should also
12617 // fail.
ttuttle859dc7a2015-04-23 19:42:2912618 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1712619 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712620 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912621 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712622 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712623
mmenkee65e7af2015-10-13 17:16:4212624 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612625 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012626 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012627
[email protected]bd0b6772011-01-11 19:59:3012628 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4112629 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912630 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12631 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012632
12633 // Complete the SSL handshake, which should abort due to requiring a
12634 // client certificate.
12635 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912636 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012637
12638 // Indicate that no certificate should be supplied. From the perspective
12639 // of SSLClientCertCache, NULL is just as meaningful as a real
12640 // certificate, so this is the same as supply a
12641 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412642 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912643 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012644
12645 // Ensure the certificate was added to the client auth cache before
12646 // allowing the connection to continue restarting.
12647 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412648 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112649 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412650 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012651 ASSERT_EQ(NULL, client_cert.get());
12652
12653 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712654 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12655 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012656 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912657 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012658
12659 // Ensure that the client certificate is removed from the cache on a
12660 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112661 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412662 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012663}
12664
12665// Ensure that a client certificate is removed from the SSL client auth
12666// cache when:
12667// 1) No proxy is involved.
12668// 2) TLS False Start is enabled.
12669// 3) The initial TLS handshake requests a client certificate.
12670// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212671TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312672 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912673 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712674 request_info.url = GURL("https://www.example.com/");
12675 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912676 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712677
[email protected]bd0b6772011-01-11 19:59:3012678 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112679 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012680
12681 // When TLS False Start is used, SSLClientSocket::Connect() calls will
12682 // return successfully after reading up to the peer's Certificate message.
12683 // This is to allow the caller to call SSLClientSocket::Write(), which can
12684 // enqueue application data to be sent in the same packet as the
12685 // ChangeCipherSpec and Finished messages.
12686 // The actual handshake will be finished when SSLClientSocket::Read() is
12687 // called, which expects to process the peer's ChangeCipherSpec and
12688 // Finished messages. If there was an error negotiating with the peer,
12689 // such as due to the peer requiring a client certificate when none was
12690 // supplied, the alert sent by the peer won't be processed until Read() is
12691 // called.
12692
12693 // Like the non-False Start case, when a client certificate is requested by
12694 // the peer, the handshake is aborted during the Connect() call.
12695 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2912696 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012697 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712698 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912699 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712700 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012701
12702 // When a client certificate is supplied, Connect() will not be aborted
12703 // when the peer requests the certificate. Instead, the handshake will
12704 // artificially succeed, allowing the caller to write the HTTP request to
12705 // the socket. The handshake messages are not processed until Read() is
12706 // called, which then detects that the handshake was aborted, due to the
12707 // peer sending a handshake_failure because it requires a client
12708 // certificate.
ttuttle859dc7a2015-04-23 19:42:2912709 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012710 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712711 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912712 MockRead data2_reads[] = {
12713 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3012714 };
ttuttle859dc7a2015-04-23 19:42:2912715 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712716 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012717
12718 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1712719 // the data for the SSL handshake once the TLSv1.1 connection falls back to
12720 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912721 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012722 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912724 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712725 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012726
[email protected]80c75f682012-05-26 16:22:1712727 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
12728 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912729 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1712730 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712731 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912732 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712733 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712734
[email protected]7799de12013-05-30 05:52:5112735 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2912736 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5112737 ssl_data5.cert_request_info = cert_request.get();
12738 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2912739 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5112740 session_deps_.socket_factory->AddSocketDataProvider(&data5);
12741
mmenkee65e7af2015-10-13 17:16:4212742 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3612743 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012744 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012745
[email protected]bd0b6772011-01-11 19:59:3012746 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4112747 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912748 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12749 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012750
12751 // Complete the SSL handshake, which should abort due to requiring a
12752 // client certificate.
12753 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912754 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012755
12756 // Indicate that no certificate should be supplied. From the perspective
12757 // of SSLClientCertCache, NULL is just as meaningful as a real
12758 // certificate, so this is the same as supply a
12759 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412760 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912761 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012762
12763 // Ensure the certificate was added to the client auth cache before
12764 // allowing the connection to continue restarting.
12765 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412766 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112767 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412768 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012769 ASSERT_EQ(NULL, client_cert.get());
12770
[email protected]bd0b6772011-01-11 19:59:3012771 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712772 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12773 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012774 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912775 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012776
12777 // Ensure that the client certificate is removed from the cache on a
12778 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112779 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412780 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012781}
12782
[email protected]8c405132011-01-11 22:03:1812783// Ensure that a client certificate is removed from the SSL client auth
12784// cache when:
12785// 1) An HTTPS proxy is involved.
12786// 3) The HTTPS proxy requests a client certificate.
12787// 4) The client supplies an invalid/unacceptable certificate for the
12788// proxy.
12789// The test is repeated twice, first for connecting to an HTTPS endpoint,
12790// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0212791TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0312792 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5112793 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712794 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1812795
12796 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112797 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1812798
12799 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
12800 // [ssl_]data[1-3]. Rather than represending the endpoint
12801 // (www.example.com:443), they represent failures with the HTTPS proxy
12802 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2912803 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1812804 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712805 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912806 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712807 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1812808
ttuttle859dc7a2015-04-23 19:42:2912809 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812810 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712811 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912812 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712813 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1812814
[email protected]80c75f682012-05-26 16:22:1712815 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
12816#if 0
ttuttle859dc7a2015-04-23 19:42:2912817 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812818 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712819 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912820 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712821 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1712822#endif
[email protected]8c405132011-01-11 22:03:1812823
ttuttle859dc7a2015-04-23 19:42:2912824 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1812825 requests[0].url = GURL("https://www.example.com/");
12826 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912827 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812828
12829 requests[1].url = GURL("http://www.example.com/");
12830 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912831 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812832
12833 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0712834 session_deps_.socket_factory->ResetNextMockIndexes();
mmenkee65e7af2015-10-13 17:16:4212835 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1812836 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012837 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1812838
12839 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4112840 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912841 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
12842 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812843
12844 // Complete the SSL handshake, which should abort due to requiring a
12845 // client certificate.
12846 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912847 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1812848
12849 // Indicate that no certificate should be supplied. From the perspective
12850 // of SSLClientCertCache, NULL is just as meaningful as a real
12851 // certificate, so this is the same as supply a
12852 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412853 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912854 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1812855
12856 // Ensure the certificate was added to the client auth cache before
12857 // allowing the connection to continue restarting.
12858 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412859 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112860 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412861 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]8c405132011-01-11 22:03:1812862 ASSERT_EQ(NULL, client_cert.get());
12863 // Ensure the certificate was NOT cached for the endpoint. This only
12864 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4112865 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412866 HostPortPair("www.example.com", 443), &client_cert,
12867 &client_private_key));
[email protected]8c405132011-01-11 22:03:1812868
12869 // Restart the handshake. This will consume ssl_data2, which fails, and
12870 // then consume ssl_data3, which should also fail. The result code is
12871 // checked against what ssl_data3 should return.
12872 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912873 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1812874
12875 // Now that the new handshake has failed, ensure that the client
12876 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4112877 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412878 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4112879 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412880 HostPortPair("www.example.com", 443), &client_cert,
12881 &client_private_key));
[email protected]8c405132011-01-11 22:03:1812882 }
12883}
12884
mmenke5c642132015-06-02 16:05:1312885TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bncf33fb31b2016-01-29 15:22:2612886 session_deps_.parse_alternative_services = true;
12887 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4612888
12889 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712890 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenkee65e7af2015-10-13 17:16:4212891 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2612892 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12893 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4612894
[email protected]8ddf8322012-02-23 18:08:0612895 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812896 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712897 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4612898
bncb03b1092016-04-06 11:19:5512899 scoped_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4912900 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812901 spdy_util_.UpdateWithStreamDestruction(1);
bncb03b1092016-04-06 11:19:5512902 scoped_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4912903 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4612904 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312905 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4612906 };
bncb03b1092016-04-06 11:19:5512907 scoped_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0212908 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
bncb03b1092016-04-06 11:19:5512909 scoped_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0212910 spdy_util_.ConstructSpdyBodyFrame(1, true));
bncb03b1092016-04-06 11:19:5512911 scoped_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0212912 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
bncb03b1092016-04-06 11:19:5512913 scoped_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0212914 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612915 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312916 CreateMockRead(*host1_resp, 1),
12917 CreateMockRead(*host1_resp_body, 2),
12918 CreateMockRead(*host2_resp, 4),
12919 CreateMockRead(*host2_resp_body, 5),
12920 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612921 };
12922
eroman36d84e54432016-03-17 03:23:0212923 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0212924 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312925 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12926 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712927 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612928
[email protected]aa22b242011-11-16 18:58:2912929 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612930 HttpRequestInfo request1;
12931 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312932 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612933 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012934 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612935
[email protected]49639fa2011-12-20 23:22:4112936 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612937 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112938 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612939
12940 const HttpResponseInfo* response = trans1.GetResponseInfo();
12941 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012942 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0212943 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612944
12945 std::string response_data;
12946 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12947 EXPECT_EQ("hello!", response_data);
12948
12949 // Preload www.gmail.com into HostCache.
12950 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1012951 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4612952 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012953 rv = session_deps_.host_resolver->Resolve(resolve_info,
12954 DEFAULT_PRIORITY,
12955 &ignored,
12956 callback.callback(),
12957 NULL,
12958 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712959 EXPECT_EQ(ERR_IO_PENDING, rv);
12960 rv = callback.WaitForResult();
12961 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612962
12963 HttpRequestInfo request2;
12964 request2.method = "GET";
12965 request2.url = GURL("https://www.gmail.com/");
12966 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012967 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612968
[email protected]49639fa2011-12-20 23:22:4112969 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612970 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112971 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612972
12973 response = trans2.GetResponseInfo();
12974 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012975 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0212976 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4612977 EXPECT_TRUE(response->was_fetched_via_spdy);
12978 EXPECT_TRUE(response->was_npn_negotiated);
12979 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12980 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612981}
12982
[email protected]23e482282013-06-14 16:08:0212983TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bncf33fb31b2016-01-29 15:22:2612984 session_deps_.parse_alternative_services = true;
12985 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d2b5f092012-06-08 23:55:0212986
12987 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0712988 session_deps_.host_resolver.reset(new MockCachingHostResolver());
mmenkee65e7af2015-10-13 17:16:4212989 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0212990 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
12991 pool_peer.DisableDomainAuthenticationVerification();
12992
12993 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812994 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712995 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0212996
bncb03b1092016-04-06 11:19:5512997 scoped_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4912998 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3812999 spdy_util_.UpdateWithStreamDestruction(1);
bncb03b1092016-04-06 11:19:5513000 scoped_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913001 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213002 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313003 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213004 };
bncb03b1092016-04-06 11:19:5513005 scoped_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213006 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
bncb03b1092016-04-06 11:19:5513007 scoped_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213008 spdy_util_.ConstructSpdyBodyFrame(1, true));
bncb03b1092016-04-06 11:19:5513009 scoped_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0213010 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
bncb03b1092016-04-06 11:19:5513011 scoped_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0213012 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213013 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1313014 CreateMockRead(*host1_resp, 1),
13015 CreateMockRead(*host1_resp_body, 2),
13016 CreateMockRead(*host2_resp, 4),
13017 CreateMockRead(*host2_resp_body, 5),
13018 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213019 };
13020
eroman36d84e54432016-03-17 03:23:0213021 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213022 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313023 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13024 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713025 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213026
13027 TestCompletionCallback callback;
13028 HttpRequestInfo request1;
13029 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313030 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213031 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013032 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213033
13034 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
13035 EXPECT_EQ(ERR_IO_PENDING, rv);
13036 EXPECT_EQ(OK, callback.WaitForResult());
13037
13038 const HttpResponseInfo* response = trans1.GetResponseInfo();
13039 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013040 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0213041 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213042
13043 std::string response_data;
13044 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
13045 EXPECT_EQ("hello!", response_data);
13046
13047 HttpRequestInfo request2;
13048 request2.method = "GET";
13049 request2.url = GURL("https://www.gmail.com/");
13050 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013051 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213052
13053 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
13054 EXPECT_EQ(ERR_IO_PENDING, rv);
13055 EXPECT_EQ(OK, callback.WaitForResult());
13056
13057 response = trans2.GetResponseInfo();
13058 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013059 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0213060 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213061 EXPECT_TRUE(response->was_fetched_via_spdy);
13062 EXPECT_TRUE(response->was_npn_negotiated);
13063 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
13064 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213065}
13066
ttuttle859dc7a2015-04-23 19:42:2913067class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4613068 public:
13069 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
13070 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013071 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613072
13073 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
13074
13075 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2013076 int Resolve(const RequestInfo& info,
13077 RequestPriority priority,
13078 AddressList* addresses,
13079 const CompletionCallback& callback,
13080 RequestHandle* out_req,
13081 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013082 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1013083 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4013084 }
13085
dchengb03027d2014-10-21 12:00:2013086 int ResolveFromCache(const RequestInfo& info,
13087 AddressList* addresses,
13088 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013089 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
13090 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0913091 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613092 return rv;
13093 }
13094
dchengb03027d2014-10-21 12:00:2013095 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4613096 host_resolver_.CancelRequest(req);
13097 }
13098
[email protected]46da33be2011-07-19 21:58:0413099 MockCachingHostResolver* GetMockHostResolver() {
13100 return &host_resolver_;
13101 }
13102
[email protected]e3ceb682011-06-28 23:55:4613103 private:
13104 MockCachingHostResolver host_resolver_;
13105 const HostPortPair host_port_;
13106};
13107
mmenke5c642132015-06-02 16:05:1313108TEST_P(HttpNetworkTransactionTest,
13109 UseIPConnectionPoolingWithHostCacheExpiration) {
bncf33fb31b2016-01-29 15:22:2613110 session_deps_.parse_alternative_services = true;
13111 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4613112
13113 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4613114 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3413115 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0713116 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4613117 params.host_resolver = &host_resolver;
mmenkee65e7af2015-10-13 17:16:4213118 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2613119 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
13120 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4613121
[email protected]8ddf8322012-02-23 18:08:0613122 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813123 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4613125
bncb03b1092016-04-06 11:19:5513126 scoped_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913127 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813128 spdy_util_.UpdateWithStreamDestruction(1);
bncb03b1092016-04-06 11:19:5513129 scoped_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913130 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613131 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313132 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613133 };
bncb03b1092016-04-06 11:19:5513134 scoped_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213135 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
bncb03b1092016-04-06 11:19:5513136 scoped_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213137 spdy_util_.ConstructSpdyBodyFrame(1, true));
bncb03b1092016-04-06 11:19:5513138 scoped_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0213139 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
bncb03b1092016-04-06 11:19:5513140 scoped_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0213141 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613142 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1313143 CreateMockRead(*host1_resp, 1),
13144 CreateMockRead(*host1_resp_body, 2),
13145 CreateMockRead(*host2_resp, 4),
13146 CreateMockRead(*host2_resp_body, 5),
13147 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613148 };
13149
eroman36d84e54432016-03-17 03:23:0213150 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213151 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313152 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13153 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713154 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613155
[email protected]aa22b242011-11-16 18:58:2913156 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613157 HttpRequestInfo request1;
13158 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313159 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613160 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013161 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613162
[email protected]49639fa2011-12-20 23:22:4113163 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613164 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113165 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613166
13167 const HttpResponseInfo* response = trans1.GetResponseInfo();
13168 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013169 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0213170 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613171
13172 std::string response_data;
13173 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
13174 EXPECT_EQ("hello!", response_data);
13175
13176 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1013177 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613178 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1013179 rv = host_resolver.Resolve(resolve_info,
13180 DEFAULT_PRIORITY,
13181 &ignored,
13182 callback.callback(),
13183 NULL,
13184 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4713185 EXPECT_EQ(ERR_IO_PENDING, rv);
13186 rv = callback.WaitForResult();
13187 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4613188
13189 HttpRequestInfo request2;
13190 request2.method = "GET";
13191 request2.url = GURL("https://www.gmail.com/");
13192 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013193 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613194
[email protected]49639fa2011-12-20 23:22:4113195 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613196 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113197 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613198
13199 response = trans2.GetResponseInfo();
13200 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013201 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0213202 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613203 EXPECT_TRUE(response->was_fetched_via_spdy);
13204 EXPECT_TRUE(response->was_npn_negotiated);
13205 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
13206 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613207}
13208
[email protected]23e482282013-06-14 16:08:0213209TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313210 const std::string https_url = "https://www.example.org:8080/";
13211 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413212
13213 // SPDY GET for HTTPS URL
bncb03b1092016-04-06 11:19:5513214 scoped_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913215 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413216
13217 MockWrite writes1[] = {
13218 CreateMockWrite(*req1, 0),
13219 };
13220
bncb03b1092016-04-06 11:19:5513221 scoped_ptr<SpdySerializedFrame> resp1(
13222 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13223 scoped_ptr<SpdySerializedFrame> body1(
13224 spdy_util_.ConstructSpdyBodyFrame(1, true));
mmenkee24011922015-12-17 22:12:5913225 MockRead reads1[] = {CreateMockRead(*resp1, 1), CreateMockRead(*body1, 2),
13226 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413227
rch8e6c6c42015-05-01 14:05:1313228 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13229 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413230 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713231 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413232
13233 // HTTP GET for the HTTP URL
13234 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313235 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413236 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313237 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413238 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413239 };
13240
13241 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313242 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13243 MockRead(ASYNC, 2, "hello"),
13244 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413245 };
13246
rch8e6c6c42015-05-01 14:05:1313247 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13248 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413249
[email protected]8450d722012-07-02 19:14:0413250 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813251 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713252 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13253 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13254 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413255
mmenkee65e7af2015-10-13 17:16:4213256 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413257
13258 // Start the first transaction to set up the SpdySession
13259 HttpRequestInfo request1;
13260 request1.method = "GET";
13261 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413262 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013263 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413264 TestCompletionCallback callback1;
13265 EXPECT_EQ(ERR_IO_PENDING,
13266 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413267 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413268
13269 EXPECT_EQ(OK, callback1.WaitForResult());
13270 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13271
13272 // Now, start the HTTP request
13273 HttpRequestInfo request2;
13274 request2.method = "GET";
13275 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413276 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013277 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413278 TestCompletionCallback callback2;
13279 EXPECT_EQ(ERR_IO_PENDING,
13280 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413281 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413282
13283 EXPECT_EQ(OK, callback2.WaitForResult());
13284 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13285}
13286
bnc1b0e36852015-04-28 15:32:5913287class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
13288 public:
13289 void Run(bool pooling, bool valid) {
13290 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
13291 443);
13292 HostPortPair alternative("www.example.org", 443);
13293
13294 base::FilePath certs_dir = GetTestCertsDirectory();
13295 scoped_refptr<X509Certificate> cert(
13296 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
13297 ASSERT_TRUE(cert.get());
13298 bool common_name_fallback_used;
13299 EXPECT_EQ(valid,
13300 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
13301 EXPECT_TRUE(
13302 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
13303 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813304 ssl.SetNextProto(GetProtocol());
bnc1b0e36852015-04-28 15:32:5913305 ssl.cert = cert;
13306 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13307
13308 // If pooling, then start a request to alternative first to create a
13309 // SpdySession.
13310 std::string url0 = "https://www.example.org:443";
13311 // Second request to origin, which has an alternative service, and could
13312 // open a connection to the alternative host or pool to the existing one.
13313 std::string url1("https://");
13314 url1.append(origin.host());
13315 url1.append(":443");
13316
bncb03b1092016-04-06 11:19:5513317 scoped_ptr<SpdySerializedFrame> req0;
13318 scoped_ptr<SpdySerializedFrame> req1;
13319 scoped_ptr<SpdySerializedFrame> resp0;
13320 scoped_ptr<SpdySerializedFrame> body0;
13321 scoped_ptr<SpdySerializedFrame> resp1;
13322 scoped_ptr<SpdySerializedFrame> body1;
bnc1b0e36852015-04-28 15:32:5913323 std::vector<MockWrite> writes;
13324 std::vector<MockRead> reads;
13325
13326 if (pooling) {
bnc38dcd392016-02-09 23:19:4913327 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813328 spdy_util_.UpdateWithStreamDestruction(1);
bnc38dcd392016-02-09 23:19:4913329 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 3, LOWEST));
bnc1b0e36852015-04-28 15:32:5913330
13331 writes.push_back(CreateMockWrite(*req0, 0));
13332 writes.push_back(CreateMockWrite(*req1, 3));
13333
13334 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13335 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13336 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
13337 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
13338
13339 reads.push_back(CreateMockRead(*resp0, 1));
13340 reads.push_back(CreateMockRead(*body0, 2));
13341 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
13342 reads.push_back(CreateMockRead(*resp1, 5));
13343 reads.push_back(CreateMockRead(*body1, 6));
13344 reads.push_back(MockRead(ASYNC, OK, 7));
13345 } else {
bnc38dcd392016-02-09 23:19:4913346 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 1, LOWEST));
bnc1b0e36852015-04-28 15:32:5913347
13348 writes.push_back(CreateMockWrite(*req1, 0));
13349
13350 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13351 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13352
13353 reads.push_back(CreateMockRead(*resp1, 1));
13354 reads.push_back(CreateMockRead(*body1, 2));
13355 reads.push_back(MockRead(ASYNC, OK, 3));
13356 }
13357
davidben5f8b6bc2015-11-25 03:19:5413358 SequencedSocketData data(reads.data(), reads.size(), writes.data(),
13359 writes.size());
bnc1b0e36852015-04-28 15:32:5913360 session_deps_.socket_factory->AddSocketDataProvider(&data);
13361
13362 // Connection to the origin fails.
13363 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13364 StaticSocketDataProvider data_refused;
13365 data_refused.set_connect_data(mock_connect);
13366 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13367
bncf33fb31b2016-01-29 15:22:2613368 session_deps_.parse_alternative_services = true;
13369 session_deps_.enable_alternative_service_with_different_host = true;
mmenkee65e7af2015-10-13 17:16:4213370 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc1b0e36852015-04-28 15:32:5913371 base::WeakPtr<HttpServerProperties> http_server_properties =
13372 session->http_server_properties();
13373 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813374 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213375 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc1b0e36852015-04-28 15:32:5913376 http_server_properties->SetAlternativeService(origin, alternative_service,
rchdc7b9052016-03-17 20:51:5013377 expiration);
bnc1b0e36852015-04-28 15:32:5913378
13379 // First request to alternative.
13380 if (pooling) {
13381 scoped_ptr<HttpTransaction> trans0(
13382 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13383 HttpRequestInfo request0;
13384 request0.method = "GET";
13385 request0.url = GURL(url0);
13386 request0.load_flags = 0;
13387 TestCompletionCallback callback0;
13388
13389 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
13390 EXPECT_EQ(ERR_IO_PENDING, rv);
13391 rv = callback0.WaitForResult();
13392 EXPECT_EQ(OK, rv);
13393 }
13394
13395 // Second request to origin.
13396 scoped_ptr<HttpTransaction> trans1(
13397 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13398 HttpRequestInfo request1;
13399 request1.method = "GET";
13400 request1.url = GURL(url1);
13401 request1.load_flags = 0;
13402 TestCompletionCallback callback1;
13403
13404 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13405 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0913406 base::MessageLoop::current()->RunUntilIdle();
mmenkee24011922015-12-17 22:12:5913407 if (data.IsPaused())
13408 data.Resume();
bnc1b0e36852015-04-28 15:32:5913409 rv = callback1.WaitForResult();
13410 if (valid) {
13411 EXPECT_EQ(OK, rv);
13412 } else {
13413 if (pooling) {
13414 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13415 } else {
13416 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
13417 }
13418 }
13419 }
13420};
13421
rdsmithebb50aa2015-11-12 03:44:3813422INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc1b0e36852015-04-28 15:32:5913423 AltSvcCertificateVerificationTest,
rdsmithebb50aa2015-11-12 03:44:3813424 testing::Values(kTestCaseSPDY31,
13425 kTestCaseHTTP2NoPriorityDependencies,
13426 kTestCaseHTTP2PriorityDependencies));
bnc1b0e36852015-04-28 15:32:5913427
13428// The alternative service host must exhibit a certificate that is valid for the
13429// origin host. Test that this is enforced when pooling to an existing
13430// connection.
13431TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
13432 Run(true, true);
13433}
13434
13435TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
13436 Run(true, false);
13437}
13438
13439// The alternative service host must exhibit a certificate that is valid for the
13440// origin host. Test that this is enforced when opening a new connection.
13441TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
13442 Run(false, true);
13443}
13444
13445TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
13446 Run(false, false);
13447}
13448
bnc5452e2a2015-05-08 16:27:4213449// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13450// with the alternative server. That connection should not be used.
13451TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
13452 HostPortPair origin("origin.example.org", 443);
13453 HostPortPair alternative("alternative.example.org", 443);
13454
13455 // Negotiate HTTP/1.1 with alternative.example.org.
13456 SSLSocketDataProvider ssl(ASYNC, OK);
13457 ssl.SetNextProto(kProtoHTTP11);
13458 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13459
13460 // No data should be read from the alternative, because HTTP/1.1 is
13461 // negotiated.
13462 StaticSocketDataProvider data;
13463 session_deps_.socket_factory->AddSocketDataProvider(&data);
13464
13465 // This test documents that an alternate Job should not be used if HTTP/1.1 is
13466 // negotiated. In order to test this, a failed connection to the origin is
13467 // mocked. This way the request relies on the alternate Job.
13468 StaticSocketDataProvider data_refused;
13469 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13470 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13471
13472 // Set up alternative service for origin.
bncf33fb31b2016-01-29 15:22:2613473 session_deps_.parse_alternative_services = true;
13474 session_deps_.enable_alternative_service_with_different_host = true;
mmenkee65e7af2015-10-13 17:16:4213475 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213476 base::WeakPtr<HttpServerProperties> http_server_properties =
13477 session->http_server_properties();
13478 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813479 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213480 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4213481 http_server_properties->SetAlternativeService(origin, alternative_service,
rchdc7b9052016-03-17 20:51:5013482 expiration);
bnc5452e2a2015-05-08 16:27:4213483
13484 scoped_ptr<HttpTransaction> trans(
13485 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13486 HttpRequestInfo request;
13487 request.method = "GET";
13488 request.url = GURL("https://origin.example.org:443");
13489 request.load_flags = 0;
13490 TestCompletionCallback callback;
13491
13492 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
13493 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
13494 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13495 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
13496}
13497
bnc40448a532015-05-11 19:13:1413498// A request to a server with an alternative service fires two Jobs: one to the
13499// origin, and an alternate one to the alternative server. If the former
13500// succeeds, the request should succeed, even if the latter fails because
13501// HTTP/1.1 is negotiated which is insufficient for alternative service.
13502TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
13503 HostPortPair origin("origin.example.org", 443);
13504 HostPortPair alternative("alternative.example.org", 443);
13505
13506 // Negotiate HTTP/1.1 with alternative.
13507 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
13508 alternative_ssl.SetNextProto(kProtoHTTP11);
13509 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13510
13511 // No data should be read from the alternative, because HTTP/1.1 is
13512 // negotiated.
13513 StaticSocketDataProvider data;
13514 session_deps_.socket_factory->AddSocketDataProvider(&data);
13515
13516 // Negotiate HTTP/1.1 with origin.
13517 SSLSocketDataProvider origin_ssl(ASYNC, OK);
13518 origin_ssl.SetNextProto(kProtoHTTP11);
13519 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13520
13521 MockWrite http_writes[] = {
13522 MockWrite(
13523 "GET / HTTP/1.1\r\n"
13524 "Host: origin.example.org\r\n"
13525 "Connection: keep-alive\r\n\r\n"),
13526 MockWrite(
13527 "GET /second HTTP/1.1\r\n"
13528 "Host: origin.example.org\r\n"
13529 "Connection: keep-alive\r\n\r\n"),
13530 };
13531
13532 MockRead http_reads[] = {
13533 MockRead("HTTP/1.1 200 OK\r\n"),
13534 MockRead("Content-Type: text/html\r\n"),
13535 MockRead("Content-Length: 6\r\n\r\n"),
13536 MockRead("foobar"),
13537 MockRead("HTTP/1.1 200 OK\r\n"),
13538 MockRead("Content-Type: text/html\r\n"),
13539 MockRead("Content-Length: 7\r\n\r\n"),
13540 MockRead("another"),
13541 };
13542 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13543 http_writes, arraysize(http_writes));
13544 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13545
13546 // Set up alternative service for origin.
bncf33fb31b2016-01-29 15:22:2613547 session_deps_.parse_alternative_services = true;
13548 session_deps_.enable_alternative_service_with_different_host = true;
mmenkee65e7af2015-10-13 17:16:4213549 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc40448a532015-05-11 19:13:1413550 base::WeakPtr<HttpServerProperties> http_server_properties =
13551 session->http_server_properties();
13552 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813553 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213554 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc40448a532015-05-11 19:13:1413555 http_server_properties->SetAlternativeService(origin, alternative_service,
rchdc7b9052016-03-17 20:51:5013556 expiration);
bnc40448a532015-05-11 19:13:1413557
13558 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13559 HttpRequestInfo request1;
13560 request1.method = "GET";
13561 request1.url = GURL("https://origin.example.org:443");
13562 request1.load_flags = 0;
13563 TestCompletionCallback callback1;
13564
13565 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
13566 rv = callback1.GetResult(rv);
13567 EXPECT_EQ(OK, rv);
13568
13569 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
13570 ASSERT_TRUE(response1 != nullptr);
13571 ASSERT_TRUE(response1->headers.get() != nullptr);
13572 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13573
13574 std::string response_data1;
13575 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
13576 EXPECT_EQ("foobar", response_data1);
13577
13578 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13579 // for alternative service.
13580 EXPECT_TRUE(
13581 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13582
13583 // Since |alternative_service| is broken, a second transaction to origin
13584 // should not start an alternate Job. It should pool to existing connection
13585 // to origin.
13586 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13587 HttpRequestInfo request2;
13588 request2.method = "GET";
13589 request2.url = GURL("https://origin.example.org:443/second");
13590 request2.load_flags = 0;
13591 TestCompletionCallback callback2;
13592
13593 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
13594 rv = callback2.GetResult(rv);
13595 EXPECT_EQ(OK, rv);
13596
13597 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
13598 ASSERT_TRUE(response2 != nullptr);
13599 ASSERT_TRUE(response2->headers.get() != nullptr);
13600 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13601
13602 std::string response_data2;
13603 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
13604 EXPECT_EQ("another", response_data2);
13605}
13606
bnc5452e2a2015-05-08 16:27:4213607// Alternative service requires HTTP/2 (or SPDY), but there is already a
13608// HTTP/1.1 socket open to the alternative server. That socket should not be
13609// used.
13610TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
13611 HostPortPair origin("origin.example.org", 443);
13612 HostPortPair alternative("alternative.example.org", 443);
13613 std::string origin_url = "https://origin.example.org:443";
13614 std::string alternative_url = "https://alternative.example.org:443";
13615
13616 // Negotiate HTTP/1.1 with alternative.example.org.
13617 SSLSocketDataProvider ssl(ASYNC, OK);
13618 ssl.SetNextProto(kProtoHTTP11);
13619 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13620
13621 // HTTP/1.1 data for |request1| and |request2|.
13622 MockWrite http_writes[] = {
13623 MockWrite(
13624 "GET / HTTP/1.1\r\n"
13625 "Host: alternative.example.org\r\n"
13626 "Connection: keep-alive\r\n\r\n"),
13627 MockWrite(
13628 "GET / HTTP/1.1\r\n"
13629 "Host: alternative.example.org\r\n"
13630 "Connection: keep-alive\r\n\r\n"),
13631 };
13632
13633 MockRead http_reads[] = {
13634 MockRead(
13635 "HTTP/1.1 200 OK\r\n"
13636 "Content-Type: text/html; charset=iso-8859-1\r\n"
13637 "Content-Length: 40\r\n\r\n"
13638 "first HTTP/1.1 response from alternative"),
13639 MockRead(
13640 "HTTP/1.1 200 OK\r\n"
13641 "Content-Type: text/html; charset=iso-8859-1\r\n"
13642 "Content-Length: 41\r\n\r\n"
13643 "second HTTP/1.1 response from alternative"),
13644 };
13645 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13646 http_writes, arraysize(http_writes));
13647 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13648
13649 // This test documents that an alternate Job should not pool to an already
13650 // existing HTTP/1.1 connection. In order to test this, a failed connection
13651 // to the origin is mocked. This way |request2| relies on the alternate Job.
13652 StaticSocketDataProvider data_refused;
13653 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13654 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13655
13656 // Set up alternative service for origin.
bncf33fb31b2016-01-29 15:22:2613657 session_deps_.parse_alternative_services = true;
13658 session_deps_.enable_alternative_service_with_different_host = false;
mmenkee65e7af2015-10-13 17:16:4213659 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc5452e2a2015-05-08 16:27:4213660 base::WeakPtr<HttpServerProperties> http_server_properties =
13661 session->http_server_properties();
13662 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813663 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213664 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4213665 http_server_properties->SetAlternativeService(origin, alternative_service,
rchdc7b9052016-03-17 20:51:5013666 expiration);
bnc5452e2a2015-05-08 16:27:4213667
13668 // First transaction to alternative to open an HTTP/1.1 socket.
13669 scoped_ptr<HttpTransaction> trans1(
13670 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13671 HttpRequestInfo request1;
13672 request1.method = "GET";
13673 request1.url = GURL(alternative_url);
13674 request1.load_flags = 0;
13675 TestCompletionCallback callback1;
13676
13677 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13678 EXPECT_EQ(OK, callback1.GetResult(rv));
13679 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13680 ASSERT_TRUE(response1);
13681 ASSERT_TRUE(response1->headers.get());
13682 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13683 EXPECT_TRUE(response1->was_npn_negotiated);
13684 EXPECT_FALSE(response1->was_fetched_via_spdy);
13685 std::string response_data1;
13686 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
13687 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
13688
13689 // Request for origin.example.org, which has an alternative service. This
13690 // will start two Jobs: the alternative looks for connections to pool to,
13691 // finds one which is HTTP/1.1, and should ignore it, and should not try to
13692 // open other connections to alternative server. The Job to origin fails, so
13693 // this request fails.
13694 scoped_ptr<HttpTransaction> trans2(
13695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13696 HttpRequestInfo request2;
13697 request2.method = "GET";
13698 request2.url = GURL(origin_url);
13699 request2.load_flags = 0;
13700 TestCompletionCallback callback2;
13701
13702 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
13703 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
13704
13705 // Another transaction to alternative. This is to test that the HTTP/1.1
13706 // socket is still open and in the pool.
13707 scoped_ptr<HttpTransaction> trans3(
13708 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13709 HttpRequestInfo request3;
13710 request3.method = "GET";
13711 request3.url = GURL(alternative_url);
13712 request3.load_flags = 0;
13713 TestCompletionCallback callback3;
13714
13715 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
13716 EXPECT_EQ(OK, callback3.GetResult(rv));
13717 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
13718 ASSERT_TRUE(response3);
13719 ASSERT_TRUE(response3->headers.get());
13720 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
13721 EXPECT_TRUE(response3->was_npn_negotiated);
13722 EXPECT_FALSE(response3->was_fetched_via_spdy);
13723 std::string response_data3;
13724 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
13725 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
13726}
13727
[email protected]23e482282013-06-14 16:08:0213728TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2313729 const std::string https_url = "https://www.example.org:8080/";
13730 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413731
rdsmithebb50aa2015-11-12 03:44:3813732 // Separate SPDY util instance for naked and wrapped requests.
13733 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
13734
[email protected]8450d722012-07-02 19:14:0413735 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2313736 const HostPortPair host_port_pair("www.example.org", 8080);
bncb03b1092016-04-06 11:19:5513737 scoped_ptr<SpdySerializedFrame> connect(
lgarrona91df87f2014-12-05 00:51:3413738 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
bncb03b1092016-04-06 11:19:5513739 scoped_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913740 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
bncb03b1092016-04-06 11:19:5513741 scoped_ptr<SpdySerializedFrame> wrapped_req1(
[email protected]23e482282013-06-14 16:08:0213742 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3913743
13744 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2913745 SpdyHeaderBlock req2_block;
bnc7ecc1122015-09-28 13:22:4913746 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]745aa9c2014-06-27 02:21:2913747 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2313748 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2913749 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4913750 req2_block[spdy_util_.GetPathKey()] = "/";
bncb03b1092016-04-06 11:19:5513751 scoped_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913752 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0413753
13754 MockWrite writes1[] = {
mmenke666a6fea2015-12-19 04:16:3313755 CreateMockWrite(*connect, 0), CreateMockWrite(*wrapped_req1, 2),
13756 CreateMockWrite(*req2, 6),
[email protected]8450d722012-07-02 19:14:0413757 };
13758
bncb03b1092016-04-06 11:19:5513759 scoped_ptr<SpdySerializedFrame> conn_resp(
bnc38dcd392016-02-09 23:19:4913760 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
bncb03b1092016-04-06 11:19:5513761 scoped_ptr<SpdySerializedFrame> resp1(
bnc38dcd392016-02-09 23:19:4913762 spdy_util_wrapped.ConstructSpdyGetSynReply(nullptr, 0, 1));
bncb03b1092016-04-06 11:19:5513763 scoped_ptr<SpdySerializedFrame> body1(
bnc38dcd392016-02-09 23:19:4913764 spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
bncb03b1092016-04-06 11:19:5513765 scoped_ptr<SpdySerializedFrame> wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3813766 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
bncb03b1092016-04-06 11:19:5513767 scoped_ptr<SpdySerializedFrame> wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3813768 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
bncb03b1092016-04-06 11:19:5513769 scoped_ptr<SpdySerializedFrame> resp2(
13770 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
13771 scoped_ptr<SpdySerializedFrame> body2(
13772 spdy_util_.ConstructSpdyBodyFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3313773 MockRead reads1[] = {
13774 CreateMockRead(*conn_resp, 1),
13775 MockRead(ASYNC, ERR_IO_PENDING, 3),
13776 CreateMockRead(*wrapped_resp1, 4),
13777 CreateMockRead(*wrapped_body1, 5),
13778 MockRead(ASYNC, ERR_IO_PENDING, 7),
13779 CreateMockRead(*resp2, 8),
13780 CreateMockRead(*body2, 9),
13781 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
13782 };
[email protected]8450d722012-07-02 19:14:0413783
mmenke666a6fea2015-12-19 04:16:3313784 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13785 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413786 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713787 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413788
rdsmith82957ad2015-09-16 19:42:0313789 session_deps_.proxy_service =
13790 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5113791 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713792 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0413793 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3813794 ssl1.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313795 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0413796 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3813797 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313798 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13799 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0413800
mmenke666a6fea2015-12-19 04:16:3313801 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0413802
13803 // Start the first transaction to set up the SpdySession
13804 HttpRequestInfo request1;
13805 request1.method = "GET";
13806 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413807 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013808 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413809 TestCompletionCallback callback1;
mmenke666a6fea2015-12-19 04:16:3313810 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0413811
mmenke666a6fea2015-12-19 04:16:3313812 // This pause is a hack to avoid running into https://crbug.com/497228.
13813 data1.RunUntilPaused();
13814 base::RunLoop().RunUntilIdle();
13815 data1.Resume();
13816 EXPECT_EQ(OK, callback1.GetResult(rv));
[email protected]8450d722012-07-02 19:14:0413817 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13818
[email protected]f6c63db52013-02-02 00:35:2213819 LoadTimingInfo load_timing_info1;
13820 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
13821 TestLoadTimingNotReusedWithPac(load_timing_info1,
13822 CONNECT_TIMING_HAS_SSL_TIMES);
13823
mmenke666a6fea2015-12-19 04:16:3313824 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0413825 HttpRequestInfo request2;
13826 request2.method = "GET";
13827 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413828 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013829 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413830 TestCompletionCallback callback2;
mmenke666a6fea2015-12-19 04:16:3313831 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0413832
mmenke666a6fea2015-12-19 04:16:3313833 // This pause is a hack to avoid running into https://crbug.com/497228.
13834 data1.RunUntilPaused();
13835 base::RunLoop().RunUntilIdle();
13836 data1.Resume();
13837 EXPECT_EQ(OK, callback2.GetResult(rv));
13838
[email protected]8450d722012-07-02 19:14:0413839 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2213840
13841 LoadTimingInfo load_timing_info2;
13842 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
13843 // The established SPDY sessions is considered reused by the HTTP request.
13844 TestLoadTimingReusedWithPac(load_timing_info2);
13845 // HTTP requests over a SPDY session should have a different connection
13846 // socket_log_id than requests over a tunnel.
13847 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0413848}
13849
[email protected]2d88e7d2012-07-19 17:55:1713850// Test that in the case where we have a SPDY session to a SPDY proxy
13851// that we do not pool other origins that resolve to the same IP when
13852// the certificate does not match the new origin.
13853// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0213854TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2313855 const std::string url1 = "http://www.example.org/";
13856 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1713857 const std::string ip_addr = "1.2.3.4";
13858
rdsmithebb50aa2015-11-12 03:44:3813859 // Second SpdyTestUtil instance for the second socket.
13860 SpdyTestUtil spdy_util_secure(GetProtocol(), GetDependenciesFromPriority());
13861
[email protected]2d88e7d2012-07-19 17:55:1713862 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0213863 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2313864 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
bncb03b1092016-04-06 11:19:5513865 scoped_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913866 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1713867
13868 MockWrite writes1[] = {
13869 CreateMockWrite(*req1, 0),
13870 };
13871
bncb03b1092016-04-06 11:19:5513872 scoped_ptr<SpdySerializedFrame> resp1(
13873 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13874 scoped_ptr<SpdySerializedFrame> body1(
13875 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1713876 MockRead reads1[] = {
mmenke666a6fea2015-12-19 04:16:3313877 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*resp1, 2),
13878 CreateMockRead(*body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1713879 };
13880
mmenke666a6fea2015-12-19 04:16:3313881 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13882 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3213883 IPAddress ip;
martijn654c8c42016-02-10 22:10:5913884 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1713885 IPEndPoint peer_addr = IPEndPoint(ip, 443);
13886 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3313887 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1713888
13889 // SPDY GET for HTTPS URL (direct)
bncb03b1092016-04-06 11:19:5513890 scoped_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913891 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1713892
13893 MockWrite writes2[] = {
13894 CreateMockWrite(*req2, 0),
13895 };
13896
bncb03b1092016-04-06 11:19:5513897 scoped_ptr<SpdySerializedFrame> resp2(
rdsmithebb50aa2015-11-12 03:44:3813898 spdy_util_secure.ConstructSpdyGetSynReply(NULL, 0, 1));
bncb03b1092016-04-06 11:19:5513899 scoped_ptr<SpdySerializedFrame> body2(
13900 spdy_util_secure.ConstructSpdyBodyFrame(1, true));
mmenke666a6fea2015-12-19 04:16:3313901 MockRead reads2[] = {CreateMockRead(*resp2, 1), CreateMockRead(*body2, 2),
13902 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1713903
mmenke666a6fea2015-12-19 04:16:3313904 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13905 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1713906 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3313907 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1713908
13909 // Set up a proxy config that sends HTTP requests to a proxy, and
13910 // all others direct.
13911 ProxyConfig proxy_config;
13912 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0713913 session_deps_.proxy_service.reset(new ProxyService(
csharrisonb7e3a082015-09-22 19:13:0413914 make_scoped_ptr(new ProxyConfigServiceFixed(proxy_config)), nullptr,
13915 NULL));
[email protected]2d88e7d2012-07-19 17:55:1713916
bncce36dca22015-04-21 22:11:2313917 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3813918 ssl1.SetNextProto(GetProtocol());
[email protected]2d88e7d2012-07-19 17:55:1713919 // Load a valid cert. Note, that this does not need to
13920 // be valid for proxy because the MockSSLClientSocket does
13921 // not actually verify it. But SpdySession will use this
13922 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2313923 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
13924 ASSERT_TRUE(ssl1.cert.get());
mmenke666a6fea2015-12-19 04:16:3313925 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
13926 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1713927
13928 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3813929 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313930 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13931 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1713932
[email protected]bb88e1d32013-05-03 23:11:0713933 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2313934 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0713935 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1713936
mmenke666a6fea2015-12-19 04:16:3313937 scoped_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1713938
13939 // Start the first transaction to set up the SpdySession
13940 HttpRequestInfo request1;
13941 request1.method = "GET";
13942 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1713943 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013944 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713945 TestCompletionCallback callback1;
13946 ASSERT_EQ(ERR_IO_PENDING,
13947 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
mmenke666a6fea2015-12-19 04:16:3313948 // This pause is a hack to avoid running into https://crbug.com/497228.
13949 data1.RunUntilPaused();
13950 base::RunLoop().RunUntilIdle();
13951 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1713952
[email protected]2d88e7d2012-07-19 17:55:1713953 EXPECT_EQ(OK, callback1.WaitForResult());
13954 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13955
13956 // Now, start the HTTP request
13957 HttpRequestInfo request2;
13958 request2.method = "GET";
13959 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1713960 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013961 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1713962 TestCompletionCallback callback2;
13963 EXPECT_EQ(ERR_IO_PENDING,
13964 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3413965 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1713966
13967 ASSERT_TRUE(callback2.have_result());
13968 EXPECT_EQ(OK, callback2.WaitForResult());
13969 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13970}
13971
[email protected]85f97342013-04-17 06:12:2413972// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
13973// error) in SPDY session, removes the socket from pool and closes the SPDY
13974// session. Verify that new url's from the same HttpNetworkSession (and a new
13975// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0213976TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2313977 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2413978
13979 MockRead reads1[] = {
13980 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
13981 };
13982
mmenke11eb5152015-06-09 14:50:5013983 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2413984
bncb03b1092016-04-06 11:19:5513985 scoped_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913986 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2413987 MockWrite writes2[] = {
13988 CreateMockWrite(*req2, 0),
13989 };
13990
bncb03b1092016-04-06 11:19:5513991 scoped_ptr<SpdySerializedFrame> resp2(
13992 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13993 scoped_ptr<SpdySerializedFrame> body2(
13994 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2413995 MockRead reads2[] = {
13996 CreateMockRead(*resp2, 1),
13997 CreateMockRead(*body2, 2),
13998 MockRead(ASYNC, OK, 3) // EOF
13999 };
14000
mmenke11eb5152015-06-09 14:50:5014001 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14002 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414003
[email protected]85f97342013-04-17 06:12:2414004 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814005 ssl1.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5014006 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14007 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414008
14009 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814010 ssl2.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5014011 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14012 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414013
mmenkee65e7af2015-10-13 17:16:4214014 scoped_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014015 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414016
14017 // Start the first transaction to set up the SpdySession and verify that
14018 // connection was closed.
14019 HttpRequestInfo request1;
14020 request1.method = "GET";
14021 request1.url = GURL(https_url);
14022 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014023 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414024 TestCompletionCallback callback1;
14025 EXPECT_EQ(ERR_IO_PENDING,
14026 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2414027 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
14028
14029 // Now, start the second request and make sure it succeeds.
14030 HttpRequestInfo request2;
14031 request2.method = "GET";
14032 request2.url = GURL(https_url);
14033 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014034 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414035 TestCompletionCallback callback2;
14036 EXPECT_EQ(ERR_IO_PENDING,
14037 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2414038
mmenke11eb5152015-06-09 14:50:5014039 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2414040 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14041}
14042
[email protected]23e482282013-06-14 16:08:0214043TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314044 ClientSocketPoolManager::set_max_sockets_per_group(
14045 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14046 ClientSocketPoolManager::set_max_sockets_per_pool(
14047 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14048
14049 // Use two different hosts with different IPs so they don't get pooled.
14050 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14051 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
mmenkee65e7af2015-10-13 17:16:4214052 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314053
14054 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814055 ssl1.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0314056 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814057 ssl2.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0314058 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14059 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14060
bncb03b1092016-04-06 11:19:5514061 scoped_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4914062 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314063 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1314064 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314065 };
bncb03b1092016-04-06 11:19:5514066 scoped_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0214067 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
bncb03b1092016-04-06 11:19:5514068 scoped_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0214069 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314070 MockRead spdy1_reads[] = {
mmenkee24011922015-12-17 22:12:5914071 CreateMockRead(*host1_resp, 1), CreateMockRead(*host1_resp_body, 2),
14072 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314073 };
14074
rdsmithebb50aa2015-11-12 03:44:3814075 // Use a separate test instance for the separate SpdySession that will be
14076 // created.
14077 SpdyTestUtil spdy_util_2(GetProtocol(), GetDependenciesFromPriority());
rch8e6c6c42015-05-01 14:05:1314078 scoped_ptr<SequencedSocketData> spdy1_data(
14079 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14080 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0314081 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14082
bncb03b1092016-04-06 11:19:5514083 scoped_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4914084 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314085 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1314086 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314087 };
bncb03b1092016-04-06 11:19:5514088 scoped_ptr<SpdySerializedFrame> host2_resp(
rdsmithebb50aa2015-11-12 03:44:3814089 spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
bncb03b1092016-04-06 11:19:5514090 scoped_ptr<SpdySerializedFrame> host2_resp_body(
rdsmithebb50aa2015-11-12 03:44:3814091 spdy_util_2.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314092 MockRead spdy2_reads[] = {
mmenkee24011922015-12-17 22:12:5914093 CreateMockRead(*host2_resp, 1), CreateMockRead(*host2_resp_body, 2),
14094 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314095 };
14096
rch8e6c6c42015-05-01 14:05:1314097 scoped_ptr<SequencedSocketData> spdy2_data(
14098 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14099 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0314100 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14101
14102 MockWrite http_write[] = {
14103 MockWrite("GET / HTTP/1.1\r\n"
14104 "Host: www.a.com\r\n"
14105 "Connection: keep-alive\r\n\r\n"),
14106 };
14107
14108 MockRead http_read[] = {
14109 MockRead("HTTP/1.1 200 OK\r\n"),
14110 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14111 MockRead("Content-Length: 6\r\n\r\n"),
14112 MockRead("hello!"),
14113 };
14114 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14115 http_write, arraysize(http_write));
14116 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14117
14118 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014119 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314120 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314121 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614122 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314123
14124 TestCompletionCallback callback;
14125 HttpRequestInfo request1;
14126 request1.method = "GET";
14127 request1.url = GURL("https://www.a.com/");
14128 request1.load_flags = 0;
14129 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5014130 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314131
14132 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
14133 EXPECT_EQ(ERR_IO_PENDING, rv);
14134 EXPECT_EQ(OK, callback.WaitForResult());
14135
14136 const HttpResponseInfo* response = trans->GetResponseInfo();
14137 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5014138 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0214139 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314140 EXPECT_TRUE(response->was_fetched_via_spdy);
14141 EXPECT_TRUE(response->was_npn_negotiated);
14142
14143 std::string response_data;
14144 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14145 EXPECT_EQ("hello!", response_data);
14146 trans.reset();
14147 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614148 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314149
14150 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014151 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314152 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314153 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614154 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314155 HttpRequestInfo request2;
14156 request2.method = "GET";
14157 request2.url = GURL("https://www.b.com/");
14158 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014159 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314160
14161 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
14162 EXPECT_EQ(ERR_IO_PENDING, rv);
14163 EXPECT_EQ(OK, callback.WaitForResult());
14164
14165 response = trans->GetResponseInfo();
14166 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5014167 ASSERT_TRUE(response->headers.get() != NULL);
bnc84e7fb52015-12-02 11:50:0214168 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314169 EXPECT_TRUE(response->was_fetched_via_spdy);
14170 EXPECT_TRUE(response->was_npn_negotiated);
14171 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14172 EXPECT_EQ("hello!", response_data);
14173 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614174 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314175 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614176 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314177
14178 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014179 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314180 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314181 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614182 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314183 HttpRequestInfo request3;
14184 request3.method = "GET";
14185 request3.url = GURL("http://www.a.com/");
14186 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014187 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314188
14189 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
14190 EXPECT_EQ(ERR_IO_PENDING, rv);
14191 EXPECT_EQ(OK, callback.WaitForResult());
14192
14193 response = trans->GetResponseInfo();
14194 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5014195 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0314196 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14197 EXPECT_FALSE(response->was_fetched_via_spdy);
14198 EXPECT_FALSE(response->was_npn_negotiated);
14199 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14200 EXPECT_EQ("hello!", response_data);
14201 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614202 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314203 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614204 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314205}
14206
[email protected]79e1fd62013-06-20 06:50:0414207TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
14208 HttpRequestInfo request;
14209 request.method = "GET";
bncce36dca22015-04-21 22:11:2314210 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414211 request.load_flags = 0;
14212
mmenkee65e7af2015-10-13 17:16:4214213 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0414214 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114215 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414216
ttuttled9dbc652015-09-29 20:00:5914217 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414218 StaticSocketDataProvider data;
14219 data.set_connect_data(mock_connect);
14220 session_deps_.socket_factory->AddSocketDataProvider(&data);
14221
14222 TestCompletionCallback callback;
14223
14224 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14225 EXPECT_EQ(ERR_IO_PENDING, rv);
14226
14227 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5914228 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0414229
[email protected]79e1fd62013-06-20 06:50:0414230 // We don't care whether this succeeds or fails, but it shouldn't crash.
14231 HttpRequestHeaders request_headers;
14232 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714233
14234 ConnectionAttempts attempts;
14235 trans->GetConnectionAttempts(&attempts);
14236 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5914237 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
14238
14239 IPEndPoint endpoint;
14240 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
14241 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414242}
14243
14244TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
14245 HttpRequestInfo request;
14246 request.method = "GET";
bncce36dca22015-04-21 22:11:2314247 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414248 request.load_flags = 0;
14249
mmenkee65e7af2015-10-13 17:16:4214250 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0414251 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114252 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414253
ttuttled9dbc652015-09-29 20:00:5914254 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414255 StaticSocketDataProvider data;
14256 data.set_connect_data(mock_connect);
14257 session_deps_.socket_factory->AddSocketDataProvider(&data);
14258
14259 TestCompletionCallback callback;
14260
14261 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14262 EXPECT_EQ(ERR_IO_PENDING, rv);
14263
14264 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5914265 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0414266
[email protected]79e1fd62013-06-20 06:50:0414267 // We don't care whether this succeeds or fails, but it shouldn't crash.
14268 HttpRequestHeaders request_headers;
14269 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714270
14271 ConnectionAttempts attempts;
14272 trans->GetConnectionAttempts(&attempts);
14273 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5914274 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
14275
14276 IPEndPoint endpoint;
14277 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
14278 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414279}
14280
14281TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
14282 HttpRequestInfo request;
14283 request.method = "GET";
bncce36dca22015-04-21 22:11:2314284 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414285 request.load_flags = 0;
14286
mmenkee65e7af2015-10-13 17:16:4214287 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0414288 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114289 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414290
14291 MockWrite data_writes[] = {
14292 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14293 };
14294 MockRead data_reads[] = {
14295 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14296 };
14297
14298 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14299 data_writes, arraysize(data_writes));
14300 session_deps_.socket_factory->AddSocketDataProvider(&data);
14301
14302 TestCompletionCallback callback;
14303
14304 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14305 EXPECT_EQ(ERR_IO_PENDING, rv);
14306
14307 rv = callback.WaitForResult();
14308 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14309
[email protected]79e1fd62013-06-20 06:50:0414310 HttpRequestHeaders request_headers;
14311 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14312 EXPECT_TRUE(request_headers.HasHeader("Host"));
14313}
14314
14315TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
14316 HttpRequestInfo request;
14317 request.method = "GET";
bncce36dca22015-04-21 22:11:2314318 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414319 request.load_flags = 0;
14320
mmenkee65e7af2015-10-13 17:16:4214321 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0414322 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114323 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414324
14325 MockWrite data_writes[] = {
14326 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14327 };
14328 MockRead data_reads[] = {
14329 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14330 };
14331
14332 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14333 data_writes, arraysize(data_writes));
14334 session_deps_.socket_factory->AddSocketDataProvider(&data);
14335
14336 TestCompletionCallback callback;
14337
14338 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14339 EXPECT_EQ(ERR_IO_PENDING, rv);
14340
14341 rv = callback.WaitForResult();
14342 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14343
[email protected]79e1fd62013-06-20 06:50:0414344 HttpRequestHeaders request_headers;
14345 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14346 EXPECT_TRUE(request_headers.HasHeader("Host"));
14347}
14348
14349TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
14350 HttpRequestInfo request;
14351 request.method = "GET";
bncce36dca22015-04-21 22:11:2314352 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414353 request.load_flags = 0;
14354
mmenkee65e7af2015-10-13 17:16:4214355 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0414356 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114357 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414358
14359 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314360 MockWrite(
14361 "GET / HTTP/1.1\r\n"
14362 "Host: www.example.org\r\n"
14363 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414364 };
14365 MockRead data_reads[] = {
14366 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14367 };
14368
14369 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14370 data_writes, arraysize(data_writes));
14371 session_deps_.socket_factory->AddSocketDataProvider(&data);
14372
14373 TestCompletionCallback callback;
14374
14375 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14376 EXPECT_EQ(ERR_IO_PENDING, rv);
14377
14378 rv = callback.WaitForResult();
14379 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14380
[email protected]79e1fd62013-06-20 06:50:0414381 HttpRequestHeaders request_headers;
14382 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14383 EXPECT_TRUE(request_headers.HasHeader("Host"));
14384}
14385
14386TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
14387 HttpRequestInfo request;
14388 request.method = "GET";
bncce36dca22015-04-21 22:11:2314389 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414390 request.load_flags = 0;
14391
mmenkee65e7af2015-10-13 17:16:4214392 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0414393 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114394 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414395
14396 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314397 MockWrite(
14398 "GET / HTTP/1.1\r\n"
14399 "Host: www.example.org\r\n"
14400 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414401 };
14402 MockRead data_reads[] = {
14403 MockRead(ASYNC, ERR_CONNECTION_RESET),
14404 };
14405
14406 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14407 data_writes, arraysize(data_writes));
14408 session_deps_.socket_factory->AddSocketDataProvider(&data);
14409
14410 TestCompletionCallback callback;
14411
14412 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14413 EXPECT_EQ(ERR_IO_PENDING, rv);
14414
14415 rv = callback.WaitForResult();
14416 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14417
[email protected]79e1fd62013-06-20 06:50:0414418 HttpRequestHeaders request_headers;
14419 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14420 EXPECT_TRUE(request_headers.HasHeader("Host"));
14421}
14422
14423TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
14424 HttpRequestInfo request;
14425 request.method = "GET";
bncce36dca22015-04-21 22:11:2314426 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414427 request.load_flags = 0;
14428 request.extra_headers.SetHeader("X-Foo", "bar");
14429
mmenkee65e7af2015-10-13 17:16:4214430 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0414431 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114432 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414433
14434 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314435 MockWrite(
14436 "GET / HTTP/1.1\r\n"
14437 "Host: www.example.org\r\n"
14438 "Connection: keep-alive\r\n"
14439 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414440 };
14441 MockRead data_reads[] = {
14442 MockRead("HTTP/1.1 200 OK\r\n"
14443 "Content-Length: 5\r\n\r\n"
14444 "hello"),
14445 MockRead(ASYNC, ERR_UNEXPECTED),
14446 };
14447
14448 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14449 data_writes, arraysize(data_writes));
14450 session_deps_.socket_factory->AddSocketDataProvider(&data);
14451
14452 TestCompletionCallback callback;
14453
14454 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14455 EXPECT_EQ(ERR_IO_PENDING, rv);
14456
14457 rv = callback.WaitForResult();
14458 EXPECT_EQ(OK, rv);
14459
14460 HttpRequestHeaders request_headers;
14461 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14462 std::string foo;
14463 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14464 EXPECT_EQ("bar", foo);
14465}
14466
[email protected]bf828982013-08-14 18:01:4714467namespace {
14468
yhiranoa7e05bb2014-11-06 05:40:3914469// Fake HttpStream that simply records calls to SetPriority().
14470class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314471 public base::SupportsWeakPtr<FakeStream> {
14472 public:
14473 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014474 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314475
14476 RequestPriority priority() const { return priority_; }
14477
dchengb03027d2014-10-21 12:00:2014478 int InitializeStream(const HttpRequestInfo* request_info,
14479 RequestPriority priority,
14480 const BoundNetLog& net_log,
14481 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314482 return ERR_IO_PENDING;
14483 }
14484
dchengb03027d2014-10-21 12:00:2014485 int SendRequest(const HttpRequestHeaders& request_headers,
14486 HttpResponseInfo* response,
14487 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314488 ADD_FAILURE();
14489 return ERR_UNEXPECTED;
14490 }
14491
dchengb03027d2014-10-21 12:00:2014492 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314493 ADD_FAILURE();
14494 return ERR_UNEXPECTED;
14495 }
14496
dchengb03027d2014-10-21 12:00:2014497 int ReadResponseBody(IOBuffer* buf,
14498 int buf_len,
14499 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314500 ADD_FAILURE();
14501 return ERR_UNEXPECTED;
14502 }
14503
dchengb03027d2014-10-21 12:00:2014504 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314505
dchengb03027d2014-10-21 12:00:2014506 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314507 ADD_FAILURE();
14508 return false;
14509 }
14510
dchengb03027d2014-10-21 12:00:2014511 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314512 ADD_FAILURE();
14513 return false;
14514 }
14515
dchengb03027d2014-10-21 12:00:2014516 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314517
mmenkebd84c392015-09-02 14:12:3414518 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314519
sclittle4de1bab92015-09-22 21:28:2414520 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914521 ADD_FAILURE();
14522 return 0;
14523 }
14524
sclittlebe1ccf62015-09-02 19:40:3614525 int64_t GetTotalSentBytes() const override {
14526 ADD_FAILURE();
14527 return 0;
14528 }
14529
dchengb03027d2014-10-21 12:00:2014530 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314531 ADD_FAILURE();
14532 return false;
14533 }
14534
dchengb03027d2014-10-21 12:00:2014535 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14536
14537 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314538 ADD_FAILURE();
14539 }
14540
ttuttled9dbc652015-09-29 20:00:5914541 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14542
nharperb7441ef2016-01-25 23:54:1414543 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14544 std::vector<uint8_t>* out) override {
14545 ADD_FAILURE();
14546 return ERR_NOT_IMPLEMENTED;
14547 }
14548
dchengb03027d2014-10-21 12:00:2014549 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314550
zhongyica364fbb2015-12-12 03:39:1214551 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14552
dchengb03027d2014-10-21 12:00:2014553 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314554
yhiranoa7e05bb2014-11-06 05:40:3914555 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
14556
14557 HttpStream* RenewStreamForAuth() override { return NULL; }
14558
[email protected]e86839fd2013-08-14 18:29:0314559 private:
14560 RequestPriority priority_;
14561
14562 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14563};
14564
14565// Fake HttpStreamRequest that simply records calls to SetPriority()
14566// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714567class FakeStreamRequest : public HttpStreamRequest,
14568 public base::SupportsWeakPtr<FakeStreamRequest> {
14569 public:
[email protected]e86839fd2013-08-14 18:29:0314570 FakeStreamRequest(RequestPriority priority,
14571 HttpStreamRequest::Delegate* delegate)
14572 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414573 delegate_(delegate),
14574 websocket_stream_create_helper_(NULL) {}
14575
14576 FakeStreamRequest(RequestPriority priority,
14577 HttpStreamRequest::Delegate* delegate,
14578 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14579 : priority_(priority),
14580 delegate_(delegate),
14581 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314582
dchengb03027d2014-10-21 12:00:2014583 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714584
14585 RequestPriority priority() const { return priority_; }
14586
[email protected]831e4a32013-11-14 02:14:4414587 const WebSocketHandshakeStreamBase::CreateHelper*
14588 websocket_stream_create_helper() const {
14589 return websocket_stream_create_helper_;
14590 }
14591
[email protected]e86839fd2013-08-14 18:29:0314592 // Create a new FakeStream and pass it to the request's
14593 // delegate. Returns a weak pointer to the FakeStream.
14594 base::WeakPtr<FakeStream> FinishStreamRequest() {
14595 FakeStream* fake_stream = new FakeStream(priority_);
14596 // Do this before calling OnStreamReady() as OnStreamReady() may
14597 // immediately delete |fake_stream|.
14598 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14599 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14600 return weak_stream;
14601 }
14602
dchengb03027d2014-10-21 12:00:2014603 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714604 ADD_FAILURE();
14605 return ERR_UNEXPECTED;
14606 }
14607
dchengb03027d2014-10-21 12:00:2014608 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714609 ADD_FAILURE();
14610 return LoadState();
14611 }
14612
dchengb03027d2014-10-21 12:00:2014613 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714614
dchengb03027d2014-10-21 12:00:2014615 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714616
dchengb03027d2014-10-21 12:00:2014617 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714618
dchengb03027d2014-10-21 12:00:2014619 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714620
ttuttle1f2d7e92015-04-28 16:17:4714621 const ConnectionAttempts& connection_attempts() const override {
14622 static ConnectionAttempts no_attempts;
14623 return no_attempts;
14624 }
14625
[email protected]bf828982013-08-14 18:01:4714626 private:
14627 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314628 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414629 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714630
14631 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14632};
14633
14634// Fake HttpStreamFactory that vends FakeStreamRequests.
14635class FakeStreamFactory : public HttpStreamFactory {
14636 public:
14637 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014638 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714639
14640 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14641 // RequestStream() (which may be NULL if it was destroyed already).
14642 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14643 return last_stream_request_;
14644 }
14645
dchengb03027d2014-10-21 12:00:2014646 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14647 RequestPriority priority,
14648 const SSLConfig& server_ssl_config,
14649 const SSLConfig& proxy_ssl_config,
14650 HttpStreamRequest::Delegate* delegate,
14651 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314652 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714653 last_stream_request_ = fake_request->AsWeakPtr();
14654 return fake_request;
14655 }
14656
xunjieli5749218c2016-03-22 16:43:0614657 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0814658 const HttpRequestInfo& info,
14659 RequestPriority priority,
14660 const SSLConfig& server_ssl_config,
14661 const SSLConfig& proxy_ssl_config,
14662 HttpStreamRequest::Delegate* delegate,
14663 const BoundNetLog& net_log) override {
14664 NOTREACHED();
14665 return nullptr;
14666 }
14667
dchengb03027d2014-10-21 12:00:2014668 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714669 const HttpRequestInfo& info,
14670 RequestPriority priority,
14671 const SSLConfig& server_ssl_config,
14672 const SSLConfig& proxy_ssl_config,
14673 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614674 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1314675 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414676 FakeStreamRequest* fake_request =
14677 new FakeStreamRequest(priority, delegate, create_helper);
14678 last_stream_request_ = fake_request->AsWeakPtr();
14679 return fake_request;
[email protected]bf828982013-08-14 18:01:4714680 }
14681
dchengb03027d2014-10-21 12:00:2014682 void PreconnectStreams(int num_streams,
14683 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2014684 const SSLConfig& server_ssl_config,
14685 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4714686 ADD_FAILURE();
14687 }
14688
dchengb03027d2014-10-21 12:00:2014689 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714690 ADD_FAILURE();
14691 return NULL;
14692 }
14693
14694 private:
14695 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14696
14697 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14698};
14699
Adam Rice425cf122015-01-19 06:18:2414700// TODO(ricea): Maybe unify this with the one in
14701// url_request_http_job_unittest.cc ?
14702class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14703 public:
14704 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
14705 bool using_proxy)
14706 : state_(connection.release(), using_proxy) {}
14707
14708 // Fake implementation of HttpStreamBase methods.
14709 // This ends up being quite "real" because this object has to really send data
14710 // on the mock socket. It might be easier to use the real implementation, but
14711 // the fact that the WebSocket code is not compiled on iOS makes that
14712 // difficult.
14713 int InitializeStream(const HttpRequestInfo* request_info,
14714 RequestPriority priority,
14715 const BoundNetLog& net_log,
14716 const CompletionCallback& callback) override {
14717 state_.Initialize(request_info, priority, net_log, callback);
14718 return OK;
14719 }
14720
14721 int SendRequest(const HttpRequestHeaders& request_headers,
14722 HttpResponseInfo* response,
14723 const CompletionCallback& callback) override {
14724 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
14725 response, callback);
14726 }
14727
14728 int ReadResponseHeaders(const CompletionCallback& callback) override {
14729 return parser()->ReadResponseHeaders(callback);
14730 }
14731
14732 int ReadResponseBody(IOBuffer* buf,
14733 int buf_len,
14734 const CompletionCallback& callback) override {
14735 NOTREACHED();
14736 return ERR_IO_PENDING;
14737 }
14738
14739 void Close(bool not_reusable) override {
14740 if (parser())
14741 parser()->Close(true);
14742 }
14743
14744 bool IsResponseBodyComplete() const override {
14745 NOTREACHED();
14746 return false;
14747 }
14748
Adam Rice425cf122015-01-19 06:18:2414749 bool IsConnectionReused() const override {
14750 NOTREACHED();
14751 return false;
14752 }
14753 void SetConnectionReused() override { NOTREACHED(); }
14754
mmenkebd84c392015-09-02 14:12:3414755 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2414756
sclittle4de1bab92015-09-22 21:28:2414757 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2414758 NOTREACHED();
14759 return 0;
14760 }
14761
sclittlebe1ccf62015-09-02 19:40:3614762 int64_t GetTotalSentBytes() const override {
14763 NOTREACHED();
14764 return 0;
14765 }
14766
Adam Rice425cf122015-01-19 06:18:2414767 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
14768 NOTREACHED();
14769 return false;
14770 }
14771
Adam Ricecb76ac62015-02-20 05:33:2514772 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2414773
14774 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
14775 NOTREACHED();
14776 }
14777
ttuttled9dbc652015-09-29 20:00:5914778 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14779
nharperb7441ef2016-01-25 23:54:1414780 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14781 std::vector<uint8_t>* out) override {
14782 ADD_FAILURE();
14783 return ERR_NOT_IMPLEMENTED;
14784 }
14785
Adam Rice425cf122015-01-19 06:18:2414786 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
14787
zhongyica364fbb2015-12-12 03:39:1214788 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14789
Adam Rice425cf122015-01-19 06:18:2414790 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
14791
14792 UploadProgress GetUploadProgress() const override {
14793 NOTREACHED();
14794 return UploadProgress();
14795 }
14796
14797 HttpStream* RenewStreamForAuth() override {
14798 NOTREACHED();
14799 return nullptr;
14800 }
14801
14802 // Fake implementation of WebSocketHandshakeStreamBase method(s)
14803 scoped_ptr<WebSocketStream> Upgrade() override {
14804 NOTREACHED();
14805 return scoped_ptr<WebSocketStream>();
14806 }
14807
14808 private:
14809 HttpStreamParser* parser() const { return state_.parser(); }
14810 HttpBasicState state_;
14811
14812 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
14813};
14814
[email protected]831e4a32013-11-14 02:14:4414815// TODO(yhirano): Split this class out into a net/websockets file, if it is
14816// worth doing.
14817class FakeWebSocketStreamCreateHelper :
14818 public WebSocketHandshakeStreamBase::CreateHelper {
14819 public:
dchengb03027d2014-10-21 12:00:2014820 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2114821 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1314822 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4814823 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2414824 using_proxy);
[email protected]831e4a32013-11-14 02:14:4414825 }
14826
dchengb03027d2014-10-21 12:00:2014827 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4414828 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1314829 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4414830 NOTREACHED();
14831 return NULL;
14832 };
14833
dchengb03027d2014-10-21 12:00:2014834 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4414835
14836 virtual scoped_ptr<WebSocketStream> Upgrade() {
14837 NOTREACHED();
14838 return scoped_ptr<WebSocketStream>();
14839 }
14840};
14841
[email protected]bf828982013-08-14 18:01:4714842} // namespace
14843
14844// Make sure that HttpNetworkTransaction passes on its priority to its
14845// stream request on start.
14846TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
mmenkee65e7af2015-10-13 17:16:4214847 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14848 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714849 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414850 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714851
dcheng48459ac22014-08-26 00:46:4114852 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714853
14854 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
14855
14856 HttpRequestInfo request;
14857 TestCompletionCallback callback;
14858 EXPECT_EQ(ERR_IO_PENDING,
14859 trans.Start(&request, callback.callback(), BoundNetLog()));
14860
14861 base::WeakPtr<FakeStreamRequest> fake_request =
14862 fake_factory->last_stream_request();
14863 ASSERT_TRUE(fake_request != NULL);
14864 EXPECT_EQ(LOW, fake_request->priority());
14865}
14866
14867// Make sure that HttpNetworkTransaction passes on its priority
14868// updates to its stream request.
14869TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
mmenkee65e7af2015-10-13 17:16:4214870 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14871 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4714872 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414873 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4714874
dcheng48459ac22014-08-26 00:46:4114875 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4714876
14877 HttpRequestInfo request;
14878 TestCompletionCallback callback;
14879 EXPECT_EQ(ERR_IO_PENDING,
14880 trans.Start(&request, callback.callback(), BoundNetLog()));
14881
14882 base::WeakPtr<FakeStreamRequest> fake_request =
14883 fake_factory->last_stream_request();
14884 ASSERT_TRUE(fake_request != NULL);
14885 EXPECT_EQ(LOW, fake_request->priority());
14886
14887 trans.SetPriority(LOWEST);
14888 ASSERT_TRUE(fake_request != NULL);
14889 EXPECT_EQ(LOWEST, fake_request->priority());
14890}
14891
[email protected]e86839fd2013-08-14 18:29:0314892// Make sure that HttpNetworkTransaction passes on its priority
14893// updates to its stream.
14894TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
mmenkee65e7af2015-10-13 17:16:4214895 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14896 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0314897 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4414898 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0314899
dcheng48459ac22014-08-26 00:46:4114900 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0314901
14902 HttpRequestInfo request;
14903 TestCompletionCallback callback;
14904 EXPECT_EQ(ERR_IO_PENDING,
14905 trans.Start(&request, callback.callback(), BoundNetLog()));
14906
14907 base::WeakPtr<FakeStreamRequest> fake_request =
14908 fake_factory->last_stream_request();
14909 ASSERT_TRUE(fake_request != NULL);
14910 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
14911 ASSERT_TRUE(fake_stream != NULL);
14912 EXPECT_EQ(LOW, fake_stream->priority());
14913
14914 trans.SetPriority(LOWEST);
14915 EXPECT_EQ(LOWEST, fake_stream->priority());
14916}
14917
[email protected]831e4a32013-11-14 02:14:4414918TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
14919 // The same logic needs to be tested for both ws: and wss: schemes, but this
14920 // test is already parameterised on NextProto, so it uses a loop to verify
14921 // that the different schemes work.
bncce36dca22015-04-21 22:11:2314922 std::string test_cases[] = {"ws://www.example.org/",
14923 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4414924 for (size_t i = 0; i < arraysize(test_cases); ++i) {
mmenkee65e7af2015-10-13 17:16:4214925 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14926 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4414927 FakeStreamFactory* fake_factory = new FakeStreamFactory();
14928 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2314929 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4414930 scoped_ptr<HttpStreamFactory>(fake_factory));
14931
dcheng48459ac22014-08-26 00:46:4114932 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4414933 trans.SetWebSocketHandshakeStreamCreateHelper(
14934 &websocket_stream_create_helper);
14935
14936 HttpRequestInfo request;
14937 TestCompletionCallback callback;
14938 request.method = "GET";
14939 request.url = GURL(test_cases[i]);
14940
14941 EXPECT_EQ(ERR_IO_PENDING,
14942 trans.Start(&request, callback.callback(), BoundNetLog()));
14943
14944 base::WeakPtr<FakeStreamRequest> fake_request =
14945 fake_factory->last_stream_request();
14946 ASSERT_TRUE(fake_request != NULL);
14947 EXPECT_EQ(&websocket_stream_create_helper,
14948 fake_request->websocket_stream_create_helper());
14949 }
14950}
14951
[email protected]043b68c82013-08-22 23:41:5214952// Tests that when a used socket is returned to the SSL socket pool, it's closed
14953// if the transport socket pool is stalled on the global socket limit.
14954TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
14955 ClientSocketPoolManager::set_max_sockets_per_group(
14956 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14957 ClientSocketPoolManager::set_max_sockets_per_pool(
14958 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14959
14960 // Set up SSL request.
14961
14962 HttpRequestInfo ssl_request;
14963 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2314964 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214965
14966 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2314967 MockWrite(
14968 "GET / HTTP/1.1\r\n"
14969 "Host: www.example.org\r\n"
14970 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214971 };
14972 MockRead ssl_reads[] = {
14973 MockRead("HTTP/1.1 200 OK\r\n"),
14974 MockRead("Content-Length: 11\r\n\r\n"),
14975 MockRead("hello world"),
14976 MockRead(SYNCHRONOUS, OK),
14977 };
14978 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
14979 ssl_writes, arraysize(ssl_writes));
14980 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
14981
14982 SSLSocketDataProvider ssl(ASYNC, OK);
14983 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14984
14985 // Set up HTTP request.
14986
14987 HttpRequestInfo http_request;
14988 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2314989 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5214990
14991 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2314992 MockWrite(
14993 "GET / HTTP/1.1\r\n"
14994 "Host: www.example.org\r\n"
14995 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5214996 };
14997 MockRead http_reads[] = {
14998 MockRead("HTTP/1.1 200 OK\r\n"),
14999 MockRead("Content-Length: 7\r\n\r\n"),
15000 MockRead("falafel"),
15001 MockRead(SYNCHRONOUS, OK),
15002 };
15003 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15004 http_writes, arraysize(http_writes));
15005 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15006
mmenkee65e7af2015-10-13 17:16:4215007 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215008
15009 // Start the SSL request.
15010 TestCompletionCallback ssl_callback;
15011 scoped_ptr<HttpTransaction> ssl_trans(
15012 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15013 ASSERT_EQ(ERR_IO_PENDING,
15014 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
15015 BoundNetLog()));
15016
15017 // Start the HTTP request. Pool should stall.
15018 TestCompletionCallback http_callback;
15019 scoped_ptr<HttpTransaction> http_trans(
15020 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15021 ASSERT_EQ(ERR_IO_PENDING,
15022 http_trans->Start(&http_request, http_callback.callback(),
15023 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4115024 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215025
15026 // Wait for response from SSL request.
15027 ASSERT_EQ(OK, ssl_callback.WaitForResult());
15028 std::string response_data;
15029 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
15030 EXPECT_EQ("hello world", response_data);
15031
15032 // The SSL socket should automatically be closed, so the HTTP request can
15033 // start.
dcheng48459ac22014-08-26 00:46:4115034 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15035 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215036
15037 // The HTTP request can now complete.
15038 ASSERT_EQ(OK, http_callback.WaitForResult());
15039 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
15040 EXPECT_EQ("falafel", response_data);
15041
dcheng48459ac22014-08-26 00:46:4115042 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215043}
15044
15045// Tests that when a SSL connection is established but there's no corresponding
15046// request that needs it, the new socket is closed if the transport socket pool
15047// is stalled on the global socket limit.
15048TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
15049 ClientSocketPoolManager::set_max_sockets_per_group(
15050 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15051 ClientSocketPoolManager::set_max_sockets_per_pool(
15052 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15053
15054 // Set up an ssl request.
15055
15056 HttpRequestInfo ssl_request;
15057 ssl_request.method = "GET";
15058 ssl_request.url = GURL("https://www.foopy.com/");
15059
15060 // No data will be sent on the SSL socket.
15061 StaticSocketDataProvider ssl_data;
15062 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15063
15064 SSLSocketDataProvider ssl(ASYNC, OK);
15065 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15066
15067 // Set up HTTP request.
15068
15069 HttpRequestInfo http_request;
15070 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315071 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215072
15073 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315074 MockWrite(
15075 "GET / HTTP/1.1\r\n"
15076 "Host: www.example.org\r\n"
15077 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215078 };
15079 MockRead http_reads[] = {
15080 MockRead("HTTP/1.1 200 OK\r\n"),
15081 MockRead("Content-Length: 7\r\n\r\n"),
15082 MockRead("falafel"),
15083 MockRead(SYNCHRONOUS, OK),
15084 };
15085 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15086 http_writes, arraysize(http_writes));
15087 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15088
mmenkee65e7af2015-10-13 17:16:4215089 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215090
15091 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15092 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915093 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
15094 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5215095 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd2015-07-15 22:26:3515096 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
15097 ssl_config);
dcheng48459ac22014-08-26 00:46:4115098 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215099
15100 // Start the HTTP request. Pool should stall.
15101 TestCompletionCallback http_callback;
15102 scoped_ptr<HttpTransaction> http_trans(
15103 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15104 ASSERT_EQ(ERR_IO_PENDING,
15105 http_trans->Start(&http_request, http_callback.callback(),
15106 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4115107 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215108
15109 // The SSL connection will automatically be closed once the connection is
15110 // established, to let the HTTP request start.
15111 ASSERT_EQ(OK, http_callback.WaitForResult());
15112 std::string response_data;
15113 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
15114 EXPECT_EQ("falafel", response_data);
15115
dcheng48459ac22014-08-26 00:46:4115116 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215117}
15118
[email protected]02d74a02014-04-23 18:10:5415119TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
olli.raula6df48b2a2015-11-26 07:40:2215120 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15121 element_readers.push_back(
15122 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15123 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415124
15125 HttpRequestInfo request;
15126 request.method = "POST";
15127 request.url = GURL("http://www.foo.com/");
15128 request.upload_data_stream = &upload_data_stream;
15129 request.load_flags = 0;
15130
mmenkee65e7af2015-10-13 17:16:4215131 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415132 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115133 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415134 // Send headers successfully, but get an error while sending the body.
15135 MockWrite data_writes[] = {
15136 MockWrite("POST / HTTP/1.1\r\n"
15137 "Host: www.foo.com\r\n"
15138 "Connection: keep-alive\r\n"
15139 "Content-Length: 3\r\n\r\n"),
15140 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15141 };
15142
15143 MockRead data_reads[] = {
15144 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15145 MockRead("hello world"),
15146 MockRead(SYNCHRONOUS, OK),
15147 };
15148 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15149 arraysize(data_writes));
15150 session_deps_.socket_factory->AddSocketDataProvider(&data);
15151
15152 TestCompletionCallback callback;
15153
15154 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15155 EXPECT_EQ(ERR_IO_PENDING, rv);
15156
15157 rv = callback.WaitForResult();
15158 EXPECT_EQ(OK, rv);
15159
15160 const HttpResponseInfo* response = trans->GetResponseInfo();
15161 ASSERT_TRUE(response != NULL);
15162
15163 EXPECT_TRUE(response->headers.get() != NULL);
15164 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15165
15166 std::string response_data;
15167 rv = ReadTransaction(trans.get(), &response_data);
15168 EXPECT_EQ(OK, rv);
15169 EXPECT_EQ("hello world", response_data);
15170}
15171
15172// This test makes sure the retry logic doesn't trigger when reading an error
15173// response from a server that rejected a POST with a CONNECTION_RESET.
15174TEST_P(HttpNetworkTransactionTest,
15175 PostReadsErrorResponseAfterResetOnReusedSocket) {
mmenkee65e7af2015-10-13 17:16:4215176 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415177 MockWrite data_writes[] = {
15178 MockWrite("GET / HTTP/1.1\r\n"
15179 "Host: www.foo.com\r\n"
15180 "Connection: keep-alive\r\n\r\n"),
15181 MockWrite("POST / HTTP/1.1\r\n"
15182 "Host: www.foo.com\r\n"
15183 "Connection: keep-alive\r\n"
15184 "Content-Length: 3\r\n\r\n"),
15185 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15186 };
15187
15188 MockRead data_reads[] = {
15189 MockRead("HTTP/1.1 200 Peachy\r\n"
15190 "Content-Length: 14\r\n\r\n"),
15191 MockRead("first response"),
15192 MockRead("HTTP/1.1 400 Not OK\r\n"
15193 "Content-Length: 15\r\n\r\n"),
15194 MockRead("second response"),
15195 MockRead(SYNCHRONOUS, OK),
15196 };
15197 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15198 arraysize(data_writes));
15199 session_deps_.socket_factory->AddSocketDataProvider(&data);
15200
15201 TestCompletionCallback callback;
15202 HttpRequestInfo request1;
15203 request1.method = "GET";
15204 request1.url = GURL("http://www.foo.com/");
15205 request1.load_flags = 0;
15206
15207 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4115208 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415209 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
15210 EXPECT_EQ(ERR_IO_PENDING, rv);
15211
15212 rv = callback.WaitForResult();
15213 EXPECT_EQ(OK, rv);
15214
15215 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
15216 ASSERT_TRUE(response1 != NULL);
15217
15218 EXPECT_TRUE(response1->headers.get() != NULL);
15219 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15220
15221 std::string response_data1;
15222 rv = ReadTransaction(trans1.get(), &response_data1);
15223 EXPECT_EQ(OK, rv);
15224 EXPECT_EQ("first response", response_data1);
15225 // Delete the transaction to release the socket back into the socket pool.
15226 trans1.reset();
15227
olli.raula6df48b2a2015-11-26 07:40:2215228 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15229 element_readers.push_back(
15230 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15231 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415232
15233 HttpRequestInfo request2;
15234 request2.method = "POST";
15235 request2.url = GURL("http://www.foo.com/");
15236 request2.upload_data_stream = &upload_data_stream;
15237 request2.load_flags = 0;
15238
15239 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4115240 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415241 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
15242 EXPECT_EQ(ERR_IO_PENDING, rv);
15243
15244 rv = callback.WaitForResult();
15245 EXPECT_EQ(OK, rv);
15246
15247 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
15248 ASSERT_TRUE(response2 != NULL);
15249
15250 EXPECT_TRUE(response2->headers.get() != NULL);
15251 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15252
15253 std::string response_data2;
15254 rv = ReadTransaction(trans2.get(), &response_data2);
15255 EXPECT_EQ(OK, rv);
15256 EXPECT_EQ("second response", response_data2);
15257}
15258
15259TEST_P(HttpNetworkTransactionTest,
15260 PostReadsErrorResponseAfterResetPartialBodySent) {
olli.raula6df48b2a2015-11-26 07:40:2215261 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15262 element_readers.push_back(
15263 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15264 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415265
15266 HttpRequestInfo request;
15267 request.method = "POST";
15268 request.url = GURL("http://www.foo.com/");
15269 request.upload_data_stream = &upload_data_stream;
15270 request.load_flags = 0;
15271
mmenkee65e7af2015-10-13 17:16:4215272 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415273 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115274 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415275 // Send headers successfully, but get an error while sending the body.
15276 MockWrite data_writes[] = {
15277 MockWrite("POST / HTTP/1.1\r\n"
15278 "Host: www.foo.com\r\n"
15279 "Connection: keep-alive\r\n"
15280 "Content-Length: 3\r\n\r\n"
15281 "fo"),
15282 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15283 };
15284
15285 MockRead data_reads[] = {
15286 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15287 MockRead("hello world"),
15288 MockRead(SYNCHRONOUS, OK),
15289 };
15290 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15291 arraysize(data_writes));
15292 session_deps_.socket_factory->AddSocketDataProvider(&data);
15293
15294 TestCompletionCallback callback;
15295
15296 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15297 EXPECT_EQ(ERR_IO_PENDING, rv);
15298
15299 rv = callback.WaitForResult();
15300 EXPECT_EQ(OK, rv);
15301
15302 const HttpResponseInfo* response = trans->GetResponseInfo();
15303 ASSERT_TRUE(response != NULL);
15304
15305 EXPECT_TRUE(response->headers.get() != NULL);
15306 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15307
15308 std::string response_data;
15309 rv = ReadTransaction(trans.get(), &response_data);
15310 EXPECT_EQ(OK, rv);
15311 EXPECT_EQ("hello world", response_data);
15312}
15313
15314// This tests the more common case than the previous test, where headers and
15315// body are not merged into a single request.
15316TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715317 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415318
15319 HttpRequestInfo request;
15320 request.method = "POST";
15321 request.url = GURL("http://www.foo.com/");
15322 request.upload_data_stream = &upload_data_stream;
15323 request.load_flags = 0;
15324
mmenkee65e7af2015-10-13 17:16:4215325 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415326 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115327 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415328 // Send headers successfully, but get an error while sending the body.
15329 MockWrite data_writes[] = {
15330 MockWrite("POST / HTTP/1.1\r\n"
15331 "Host: www.foo.com\r\n"
15332 "Connection: keep-alive\r\n"
15333 "Transfer-Encoding: chunked\r\n\r\n"),
15334 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15335 };
15336
15337 MockRead data_reads[] = {
15338 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15339 MockRead("hello world"),
15340 MockRead(SYNCHRONOUS, OK),
15341 };
15342 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15343 arraysize(data_writes));
15344 session_deps_.socket_factory->AddSocketDataProvider(&data);
15345
15346 TestCompletionCallback callback;
15347
15348 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15349 EXPECT_EQ(ERR_IO_PENDING, rv);
15350 // Make sure the headers are sent before adding a chunk. This ensures that
15351 // they can't be merged with the body in a single send. Not currently
15352 // necessary since a chunked body is never merged with headers, but this makes
15353 // the test more future proof.
15354 base::RunLoop().RunUntilIdle();
15355
mmenkecbc2b712014-10-09 20:29:0715356 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415357
15358 rv = callback.WaitForResult();
15359 EXPECT_EQ(OK, rv);
15360
15361 const HttpResponseInfo* response = trans->GetResponseInfo();
15362 ASSERT_TRUE(response != NULL);
15363
15364 EXPECT_TRUE(response->headers.get() != NULL);
15365 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15366
15367 std::string response_data;
15368 rv = ReadTransaction(trans.get(), &response_data);
15369 EXPECT_EQ(OK, rv);
15370 EXPECT_EQ("hello world", response_data);
15371}
15372
15373TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
olli.raula6df48b2a2015-11-26 07:40:2215374 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15375 element_readers.push_back(
15376 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15377 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415378
15379 HttpRequestInfo request;
15380 request.method = "POST";
15381 request.url = GURL("http://www.foo.com/");
15382 request.upload_data_stream = &upload_data_stream;
15383 request.load_flags = 0;
15384
mmenkee65e7af2015-10-13 17:16:4215385 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415386 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115387 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415388
15389 MockWrite data_writes[] = {
15390 MockWrite("POST / HTTP/1.1\r\n"
15391 "Host: www.foo.com\r\n"
15392 "Connection: keep-alive\r\n"
15393 "Content-Length: 3\r\n\r\n"),
15394 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15395 };
15396
15397 MockRead data_reads[] = {
15398 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15399 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15400 MockRead("hello world"),
15401 MockRead(SYNCHRONOUS, OK),
15402 };
15403 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15404 arraysize(data_writes));
15405 session_deps_.socket_factory->AddSocketDataProvider(&data);
15406
15407 TestCompletionCallback callback;
15408
15409 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15410 EXPECT_EQ(ERR_IO_PENDING, rv);
15411
15412 rv = callback.WaitForResult();
15413 EXPECT_EQ(OK, rv);
15414
15415 const HttpResponseInfo* response = trans->GetResponseInfo();
15416 ASSERT_TRUE(response != NULL);
15417
15418 EXPECT_TRUE(response->headers.get() != NULL);
15419 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15420
15421 std::string response_data;
15422 rv = ReadTransaction(trans.get(), &response_data);
15423 EXPECT_EQ(OK, rv);
15424 EXPECT_EQ("hello world", response_data);
15425}
15426
15427TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
olli.raula6df48b2a2015-11-26 07:40:2215428 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15429 element_readers.push_back(
15430 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15431 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415432
15433 HttpRequestInfo request;
15434 request.method = "POST";
15435 request.url = GURL("http://www.foo.com/");
15436 request.upload_data_stream = &upload_data_stream;
15437 request.load_flags = 0;
15438
mmenkee65e7af2015-10-13 17:16:4215439 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415440 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115441 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415442 // Send headers successfully, but get an error while sending the body.
15443 MockWrite data_writes[] = {
15444 MockWrite("POST / HTTP/1.1\r\n"
15445 "Host: www.foo.com\r\n"
15446 "Connection: keep-alive\r\n"
15447 "Content-Length: 3\r\n\r\n"),
15448 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15449 };
15450
15451 MockRead data_reads[] = {
15452 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15453 MockRead("hello world"),
15454 MockRead(SYNCHRONOUS, OK),
15455 };
15456 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15457 arraysize(data_writes));
15458 session_deps_.socket_factory->AddSocketDataProvider(&data);
15459
15460 TestCompletionCallback callback;
15461
15462 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15463 EXPECT_EQ(ERR_IO_PENDING, rv);
15464
15465 rv = callback.WaitForResult();
15466 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415467}
15468
15469TEST_P(HttpNetworkTransactionTest,
15470 PostIgnoresNonErrorResponseAfterResetAnd100) {
olli.raula6df48b2a2015-11-26 07:40:2215471 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15472 element_readers.push_back(
15473 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15474 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415475
15476 HttpRequestInfo request;
15477 request.method = "POST";
15478 request.url = GURL("http://www.foo.com/");
15479 request.upload_data_stream = &upload_data_stream;
15480 request.load_flags = 0;
15481
mmenkee65e7af2015-10-13 17:16:4215482 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415483 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115484 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415485 // Send headers successfully, but get an error while sending the body.
15486 MockWrite data_writes[] = {
15487 MockWrite("POST / HTTP/1.1\r\n"
15488 "Host: www.foo.com\r\n"
15489 "Connection: keep-alive\r\n"
15490 "Content-Length: 3\r\n\r\n"),
15491 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15492 };
15493
15494 MockRead data_reads[] = {
15495 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15496 MockRead("HTTP/1.0 302 Redirect\r\n"),
15497 MockRead("Location: http://somewhere-else.com/\r\n"),
15498 MockRead("Content-Length: 0\r\n\r\n"),
15499 MockRead(SYNCHRONOUS, OK),
15500 };
15501 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15502 arraysize(data_writes));
15503 session_deps_.socket_factory->AddSocketDataProvider(&data);
15504
15505 TestCompletionCallback callback;
15506
15507 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15508 EXPECT_EQ(ERR_IO_PENDING, rv);
15509
15510 rv = callback.WaitForResult();
15511 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415512}
15513
15514TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
olli.raula6df48b2a2015-11-26 07:40:2215515 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15516 element_readers.push_back(
15517 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15518 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415519
15520 HttpRequestInfo request;
15521 request.method = "POST";
15522 request.url = GURL("http://www.foo.com/");
15523 request.upload_data_stream = &upload_data_stream;
15524 request.load_flags = 0;
15525
mmenkee65e7af2015-10-13 17:16:4215526 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415527 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115528 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415529 // Send headers successfully, but get an error while sending the body.
15530 MockWrite data_writes[] = {
15531 MockWrite("POST / HTTP/1.1\r\n"
15532 "Host: www.foo.com\r\n"
15533 "Connection: keep-alive\r\n"
15534 "Content-Length: 3\r\n\r\n"),
15535 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15536 };
15537
15538 MockRead data_reads[] = {
15539 MockRead("HTTP 0.9 rocks!"),
15540 MockRead(SYNCHRONOUS, OK),
15541 };
15542 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15543 arraysize(data_writes));
15544 session_deps_.socket_factory->AddSocketDataProvider(&data);
15545
15546 TestCompletionCallback callback;
15547
15548 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15549 EXPECT_EQ(ERR_IO_PENDING, rv);
15550
15551 rv = callback.WaitForResult();
15552 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415553}
15554
15555TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
olli.raula6df48b2a2015-11-26 07:40:2215556 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15557 element_readers.push_back(
15558 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15559 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415560
15561 HttpRequestInfo request;
15562 request.method = "POST";
15563 request.url = GURL("http://www.foo.com/");
15564 request.upload_data_stream = &upload_data_stream;
15565 request.load_flags = 0;
15566
mmenkee65e7af2015-10-13 17:16:4215567 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415568 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115569 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415570 // Send headers successfully, but get an error while sending the body.
15571 MockWrite data_writes[] = {
15572 MockWrite("POST / HTTP/1.1\r\n"
15573 "Host: www.foo.com\r\n"
15574 "Connection: keep-alive\r\n"
15575 "Content-Length: 3\r\n\r\n"),
15576 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15577 };
15578
15579 MockRead data_reads[] = {
15580 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15581 MockRead(SYNCHRONOUS, OK),
15582 };
15583 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15584 arraysize(data_writes));
15585 session_deps_.socket_factory->AddSocketDataProvider(&data);
15586
15587 TestCompletionCallback callback;
15588
15589 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15590 EXPECT_EQ(ERR_IO_PENDING, rv);
15591
15592 rv = callback.WaitForResult();
15593 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415594}
15595
Adam Rice425cf122015-01-19 06:18:2415596// Verify that proxy headers are not sent to the destination server when
15597// establishing a tunnel for a secure WebSocket connection.
15598TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
15599 HttpRequestInfo request;
15600 request.method = "GET";
bncce36dca22015-04-21 22:11:2315601 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415602 AddWebSocketHeaders(&request.extra_headers);
15603
15604 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315605 session_deps_.proxy_service =
15606 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415607
mmenkee65e7af2015-10-13 17:16:4215608 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415609
15610 // Since a proxy is configured, try to establish a tunnel.
15611 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715612 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15613 "Host: www.example.org:443\r\n"
15614 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415615
15616 // After calling trans->RestartWithAuth(), this is the request we should
15617 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1715618 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15619 "Host: www.example.org:443\r\n"
15620 "Proxy-Connection: keep-alive\r\n"
15621 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415622
rsleevidb16bb02015-11-12 23:47:1715623 MockWrite("GET / HTTP/1.1\r\n"
15624 "Host: www.example.org\r\n"
15625 "Connection: Upgrade\r\n"
15626 "Upgrade: websocket\r\n"
15627 "Origin: http://www.example.org\r\n"
15628 "Sec-WebSocket-Version: 13\r\n"
15629 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415630 };
15631
15632 // The proxy responds to the connect with a 407, using a persistent
15633 // connection.
15634 MockRead data_reads[] = {
15635 // No credentials.
15636 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15637 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415638 MockRead("Content-Length: 0\r\n"),
15639 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415640
15641 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15642
15643 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15644 MockRead("Upgrade: websocket\r\n"),
15645 MockRead("Connection: Upgrade\r\n"),
15646 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15647 };
15648
15649 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15650 arraysize(data_writes));
15651 session_deps_.socket_factory->AddSocketDataProvider(&data);
15652 SSLSocketDataProvider ssl(ASYNC, OK);
15653 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15654
15655 scoped_ptr<HttpTransaction> trans(
15656 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15657 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15658 trans->SetWebSocketHandshakeStreamCreateHelper(
15659 &websocket_stream_create_helper);
15660
15661 {
15662 TestCompletionCallback callback;
15663
15664 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15665 EXPECT_EQ(ERR_IO_PENDING, rv);
15666
15667 rv = callback.WaitForResult();
15668 EXPECT_EQ(OK, rv);
15669 }
15670
15671 const HttpResponseInfo* response = trans->GetResponseInfo();
15672 ASSERT_TRUE(response);
15673 ASSERT_TRUE(response->headers.get());
15674 EXPECT_EQ(407, response->headers->response_code());
15675
15676 {
15677 TestCompletionCallback callback;
15678
15679 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15680 callback.callback());
15681 EXPECT_EQ(ERR_IO_PENDING, rv);
15682
15683 rv = callback.WaitForResult();
15684 EXPECT_EQ(OK, rv);
15685 }
15686
15687 response = trans->GetResponseInfo();
15688 ASSERT_TRUE(response);
15689 ASSERT_TRUE(response->headers.get());
15690
15691 EXPECT_EQ(101, response->headers->response_code());
15692
15693 trans.reset();
15694 session->CloseAllConnections();
15695}
15696
15697// Verify that proxy headers are not sent to the destination server when
15698// establishing a tunnel for an insecure WebSocket connection.
15699// This requires the authentication info to be injected into the auth cache
15700// due to crbug.com/395064
15701// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
15702TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
15703 HttpRequestInfo request;
15704 request.method = "GET";
bncce36dca22015-04-21 22:11:2315705 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415706 AddWebSocketHeaders(&request.extra_headers);
15707
15708 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315709 session_deps_.proxy_service =
15710 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415711
mmenkee65e7af2015-10-13 17:16:4215712 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415713
15714 MockWrite data_writes[] = {
15715 // Try to establish a tunnel for the WebSocket connection, with
15716 // credentials. Because WebSockets have a separate set of socket pools,
15717 // they cannot and will not use the same TCP/IP connection as the
15718 // preflight HTTP request.
15719 MockWrite(
bncce36dca22015-04-21 22:11:2315720 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15721 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415722 "Proxy-Connection: keep-alive\r\n"
15723 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15724
15725 MockWrite(
15726 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315727 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415728 "Connection: Upgrade\r\n"
15729 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315730 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415731 "Sec-WebSocket-Version: 13\r\n"
15732 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15733 };
15734
15735 MockRead data_reads[] = {
15736 // HTTP CONNECT with credentials.
15737 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15738
15739 // WebSocket connection established inside tunnel.
15740 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15741 MockRead("Upgrade: websocket\r\n"),
15742 MockRead("Connection: Upgrade\r\n"),
15743 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15744 };
15745
15746 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15747 arraysize(data_writes));
15748 session_deps_.socket_factory->AddSocketDataProvider(&data);
15749
15750 session->http_auth_cache()->Add(
15751 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
15752 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
15753
15754 scoped_ptr<HttpTransaction> trans(
15755 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15756 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15757 trans->SetWebSocketHandshakeStreamCreateHelper(
15758 &websocket_stream_create_helper);
15759
15760 TestCompletionCallback callback;
15761
15762 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15763 EXPECT_EQ(ERR_IO_PENDING, rv);
15764
15765 rv = callback.WaitForResult();
15766 EXPECT_EQ(OK, rv);
15767
15768 const HttpResponseInfo* response = trans->GetResponseInfo();
15769 ASSERT_TRUE(response);
15770 ASSERT_TRUE(response->headers.get());
15771
15772 EXPECT_EQ(101, response->headers->response_code());
15773
15774 trans.reset();
15775 session->CloseAllConnections();
15776}
15777
sclittlefb249892015-09-10 21:33:2215778TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
olli.raula6df48b2a2015-11-26 07:40:2215779 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15780 element_readers.push_back(
15781 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15782 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215783
15784 HttpRequestInfo request;
15785 request.method = "POST";
15786 request.url = GURL("http://www.foo.com/");
15787 request.upload_data_stream = &upload_data_stream;
15788
mmenkee65e7af2015-10-13 17:16:4215789 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215790 scoped_ptr<HttpTransaction> trans(
15791 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15792 MockWrite data_writes[] = {
15793 MockWrite("POST / HTTP/1.1\r\n"
15794 "Host: www.foo.com\r\n"
15795 "Connection: keep-alive\r\n"
15796 "Content-Length: 3\r\n\r\n"),
15797 MockWrite("foo"),
15798 };
15799
15800 MockRead data_reads[] = {
15801 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15802 MockRead(SYNCHRONOUS, OK),
15803 };
15804 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15805 arraysize(data_writes));
15806 session_deps_.socket_factory->AddSocketDataProvider(&data);
15807
15808 TestCompletionCallback callback;
15809
15810 EXPECT_EQ(ERR_IO_PENDING,
15811 trans->Start(&request, callback.callback(), BoundNetLog()));
15812 EXPECT_EQ(OK, callback.WaitForResult());
15813
15814 std::string response_data;
15815 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15816
15817 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15818 trans->GetTotalSentBytes());
15819 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15820 trans->GetTotalReceivedBytes());
15821}
15822
15823TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
olli.raula6df48b2a2015-11-26 07:40:2215824 std::vector<scoped_ptr<UploadElementReader>> element_readers;
15825 element_readers.push_back(
15826 make_scoped_ptr(new UploadBytesElementReader("foo", 3)));
15827 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215828
15829 HttpRequestInfo request;
15830 request.method = "POST";
15831 request.url = GURL("http://www.foo.com/");
15832 request.upload_data_stream = &upload_data_stream;
15833
mmenkee65e7af2015-10-13 17:16:4215834 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215835 scoped_ptr<HttpTransaction> trans(
15836 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15837 MockWrite data_writes[] = {
15838 MockWrite("POST / HTTP/1.1\r\n"
15839 "Host: www.foo.com\r\n"
15840 "Connection: keep-alive\r\n"
15841 "Content-Length: 3\r\n\r\n"),
15842 MockWrite("foo"),
15843 };
15844
15845 MockRead data_reads[] = {
15846 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
15847 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15848 MockRead(SYNCHRONOUS, OK),
15849 };
15850 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15851 arraysize(data_writes));
15852 session_deps_.socket_factory->AddSocketDataProvider(&data);
15853
15854 TestCompletionCallback callback;
15855
15856 EXPECT_EQ(ERR_IO_PENDING,
15857 trans->Start(&request, callback.callback(), BoundNetLog()));
15858 EXPECT_EQ(OK, callback.WaitForResult());
15859
15860 std::string response_data;
15861 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15862
15863 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15864 trans->GetTotalSentBytes());
15865 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15866 trans->GetTotalReceivedBytes());
15867}
15868
15869TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2215870 ChunkedUploadDataStream upload_data_stream(0);
15871
15872 HttpRequestInfo request;
15873 request.method = "POST";
15874 request.url = GURL("http://www.foo.com/");
15875 request.upload_data_stream = &upload_data_stream;
15876
mmenkee65e7af2015-10-13 17:16:4215877 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
sclittlefb249892015-09-10 21:33:2215878 scoped_ptr<HttpTransaction> trans(
15879 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15880 // Send headers successfully, but get an error while sending the body.
15881 MockWrite data_writes[] = {
15882 MockWrite("POST / HTTP/1.1\r\n"
15883 "Host: www.foo.com\r\n"
15884 "Connection: keep-alive\r\n"
15885 "Transfer-Encoding: chunked\r\n\r\n"),
15886 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
15887 };
15888
15889 MockRead data_reads[] = {
15890 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15891 MockRead(SYNCHRONOUS, OK),
15892 };
15893 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15894 arraysize(data_writes));
15895 session_deps_.socket_factory->AddSocketDataProvider(&data);
15896
15897 TestCompletionCallback callback;
15898
15899 EXPECT_EQ(ERR_IO_PENDING,
15900 trans->Start(&request, callback.callback(), BoundNetLog()));
15901
15902 base::RunLoop().RunUntilIdle();
15903 upload_data_stream.AppendData("f", 1, false);
15904
15905 base::RunLoop().RunUntilIdle();
15906 upload_data_stream.AppendData("oo", 2, true);
15907
15908 EXPECT_EQ(OK, callback.WaitForResult());
15909
15910 std::string response_data;
15911 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15912
15913 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15914 trans->GetTotalSentBytes());
15915 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15916 trans->GetTotalReceivedBytes());
15917}
15918
bncf4588402015-11-24 13:33:1815919TEST_P(HttpNetworkTransactionTest, EnableNPN) {
bncf4588402015-11-24 13:33:1815920 session_deps_.enable_npn = true;
15921
15922 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15923 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15924
15925 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
15926 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15927 EXPECT_THAT(trans.server_ssl_config_.npn_protos,
15928 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15929}
15930
15931TEST_P(HttpNetworkTransactionTest, DisableNPN) {
bncf4588402015-11-24 13:33:1815932 session_deps_.enable_npn = false;
15933
15934 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15935 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15936
15937 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
15938 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
15939 EXPECT_TRUE(trans.server_ssl_config_.npn_protos.empty());
15940}
15941
nharperb7441ef2016-01-25 23:54:1415942#if !defined(OS_IOS)
15943TEST_P(HttpNetworkTransactionTest, TokenBindingSpdy) {
15944 const std::string https_url = "https://www.example.com";
15945 HttpRequestInfo request;
15946 request.url = GURL(https_url);
15947 request.method = "GET";
15948
15949 SSLSocketDataProvider ssl(ASYNC, OK);
15950 ssl.token_binding_negotiated = true;
15951 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
15952 ssl.SetNextProto(GetProtocol());
15953 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15954
bncb03b1092016-04-06 11:19:5515955 scoped_ptr<SpdySerializedFrame> resp(
nharperb7441ef2016-01-25 23:54:1415956 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
bncb03b1092016-04-06 11:19:5515957 scoped_ptr<SpdySerializedFrame> body(
15958 spdy_util_.ConstructSpdyBodyFrame(1, true));
nharperb7441ef2016-01-25 23:54:1415959 MockRead reads[] = {CreateMockRead(*resp), CreateMockRead(*body),
15960 MockRead(ASYNC, ERR_IO_PENDING)};
15961 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
15962 session_deps_.socket_factory->AddSocketDataProvider(&data);
15963 session_deps_.channel_id_service.reset(new ChannelIDService(
15964 new DefaultChannelIDStore(nullptr), base::ThreadTaskRunnerHandle::Get()));
15965 scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15966
15967 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15968 TestCompletionCallback callback;
15969 EXPECT_EQ(ERR_IO_PENDING,
15970 trans.Start(&request, callback.callback(), BoundNetLog()));
15971 base::MessageLoop::current()->RunUntilIdle();
15972
15973 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
15974 HttpRequestHeaders headers;
15975 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
15976 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
15977}
15978#endif // !defined(OS_IOS)
15979
[email protected]89ceba9a2009-03-21 03:46:0615980} // namespace net