blob: accad7da16fc38fe9be8d00e0f6394985b61992b [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>
9#include <string>
[email protected]95d88ffe2010-02-04 21:25:3310#include <vector>
[email protected]77848d12008-11-14 00:00:2211
[email protected]2d731a32010-04-29 01:04:0612#include "base/basictypes.h"
[email protected]68bf9152008-09-25 19:47:3013#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5214#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2915#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5716#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2417#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1518#include "base/memory/scoped_ptr.h"
[email protected]bf828982013-08-14 18:01:4719#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4920#include "base/run_loop.h"
bnc1b0e36852015-04-28 15:32:5921#include "base/stl_util.h"
[email protected]125ef482013-06-11 18:32:4722#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0523#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3324#include "base/test/test_file_util.h"
skyostil4891b25b2015-06-11 11:43:4525#include "base/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3526#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0727#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3328#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0729#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2530#include "net/base/load_timing_info.h"
31#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2432#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3133#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5234#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4035#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0636#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2137#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1138#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1639#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5340#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2441#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1242#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0043#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2944#include "net/http/http_auth_handler_ntlm.h"
Adam Rice425cf122015-01-19 06:18:2445#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5746#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5247#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5648#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2449#include "net/http/http_request_headers.h"
[email protected]17291a022011-10-10 07:32:5350#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5751#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3852#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2453#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1954#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0755#include "net/log/net_log.h"
vishal.b62985ca92015-04-17 08:45:5156#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4657#include "net/log/test_net_log_entry.h"
58#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1359#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5360#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0361#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1162#include "net/proxy/proxy_resolver.h"
63#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4464#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0365#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4766#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0267#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0768#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4469#include "net/socket/socket_test_util.h"
70#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5471#include "net/spdy/spdy_framer.h"
72#include "net/spdy/spdy_session.h"
73#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0274#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5775#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0376#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5777#include "net/ssl/ssl_config_service_defaults.h"
78#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1179#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4480#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5281#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1582#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2783#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5284
[email protected]ad65a3e2013-12-25 18:18:0185using base::ASCIIToUTF16;
86
initial.commit586acc5fe2008-07-26 22:42:5287//-----------------------------------------------------------------------------
88
ttuttle859dc7a2015-04-23 19:42:2989namespace net {
90
[email protected]13c8a092010-07-29 06:15:4491namespace {
92
[email protected]42cba2fb2013-03-29 19:58:5793const base::string16 kBar(ASCIIToUTF16("bar"));
94const base::string16 kBar2(ASCIIToUTF16("bar2"));
95const base::string16 kBar3(ASCIIToUTF16("bar3"));
96const base::string16 kBaz(ASCIIToUTF16("baz"));
97const base::string16 kFirst(ASCIIToUTF16("first"));
98const base::string16 kFoo(ASCIIToUTF16("foo"));
99const base::string16 kFoo2(ASCIIToUTF16("foo2"));
100const base::string16 kFoo3(ASCIIToUTF16("foo3"));
101const base::string16 kFou(ASCIIToUTF16("fou"));
102const base::string16 kSecond(ASCIIToUTF16("second"));
103const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
104const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44105
ttuttle859dc7a2015-04-23 19:42:29106int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
107 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
108 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02109}
110
ttuttle859dc7a2015-04-23 19:42:29111int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
112 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
113 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02114}
115
ttuttle859dc7a2015-04-23 19:42:29116bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
117 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
118 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52119}
120
[email protected]f3da152d2012-06-02 01:00:57121// Takes in a Value created from a NetLogHttpResponseParameter, and returns
122// a JSONified list of headers as a single string. Uses single quotes instead
123// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27124bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57125 if (!params)
126 return false;
[email protected]ea5ef4c2013-06-13 22:50:27127 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57128 if (!params->GetList("headers", &header_list))
129 return false;
130 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34131 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28132 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57133 return true;
134}
135
[email protected]029c83b62013-01-24 05:28:20136// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
137// used.
ttuttle859dc7a2015-04-23 19:42:29138void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20139 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29140 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25141
[email protected]029c83b62013-01-24 05:28:20142 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
143 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
144
ttuttle859dc7a2015-04-23 19:42:29145 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20146 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25147
148 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25149
[email protected]3b23a222013-05-15 21:33:25150 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25151 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
152 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25153 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25154}
155
[email protected]029c83b62013-01-24 05:28:20156// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
157// used.
ttuttle859dc7a2015-04-23 19:42:29158void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25159 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20160 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29161 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20162
163 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
164 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
165
ttuttle859dc7a2015-04-23 19:42:29166 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
167 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20168 EXPECT_LE(load_timing_info.connect_timing.connect_end,
169 load_timing_info.send_start);
170
171 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20172
[email protected]3b23a222013-05-15 21:33:25173 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20174 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]029c83b62013-01-24 05:28:20177}
178
179// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
180// used.
ttuttle859dc7a2015-04-23 19:42:29181void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20182 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29183 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20184
ttuttle859dc7a2015-04-23 19:42:29185 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20186
187 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
188 EXPECT_LE(load_timing_info.proxy_resolve_start,
189 load_timing_info.proxy_resolve_end);
190 EXPECT_LE(load_timing_info.proxy_resolve_end,
191 load_timing_info.send_start);
192 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20193
[email protected]3b23a222013-05-15 21:33:25194 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20195 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
196 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25197 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20198}
199
200// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
201// used.
ttuttle859dc7a2015-04-23 19:42:29202void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20203 int connect_timing_flags) {
204 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29205 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20206
207 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
208 EXPECT_LE(load_timing_info.proxy_resolve_start,
209 load_timing_info.proxy_resolve_end);
210 EXPECT_LE(load_timing_info.proxy_resolve_end,
211 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29212 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
213 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20214 EXPECT_LE(load_timing_info.connect_timing.connect_end,
215 load_timing_info.send_start);
216
217 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20218
[email protected]3b23a222013-05-15 21:33:25219 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20220 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
221 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25222 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25223}
224
ttuttle859dc7a2015-04-23 19:42:29225void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24226 headers->SetHeader("Connection", "Upgrade");
227 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23228 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24229 headers->SetHeader("Sec-WebSocket-Version", "13");
230 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
231}
232
[email protected]c6bf8152012-12-02 07:43:34233HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
234 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14235}
236
[email protected]448d4ca52012-03-04 04:12:23237} // namespace
238
[email protected]23e482282013-06-14 16:08:02239class HttpNetworkTransactionTest
240 : public PlatformTest,
241 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03242 public:
[email protected]23e482282013-06-14 16:08:02243 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03244 // Important to restore the per-pool limit first, since the pool limit must
245 // always be greater than group limit, and the tests reduce both limits.
246 ClientSocketPoolManager::set_max_sockets_per_pool(
247 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
248 ClientSocketPoolManager::set_max_sockets_per_group(
249 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
250 }
251
[email protected]e3ceb682011-06-28 23:55:46252 protected:
[email protected]23e482282013-06-14 16:08:02253 HttpNetworkTransactionTest()
254 : spdy_util_(GetParam()),
255 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03256 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
257 HttpNetworkSession::NORMAL_SOCKET_POOL)),
258 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
259 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
260 }
[email protected]bb88e1d32013-05-03 23:11:07261
[email protected]e3ceb682011-06-28 23:55:46262 struct SimpleGetHelperResult {
263 int rv;
264 std::string status_line;
265 std::string response_data;
[email protected]b8015c42013-12-24 15:18:19266 int64 totalReceivedBytes;
[email protected]58e32bb2013-01-21 18:23:25267 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47268 ConnectionAttempts connection_attempts;
[email protected]e3ceb682011-06-28 23:55:46269 };
270
dcheng67be2b1f2014-10-27 21:47:29271 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50272 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34273 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54274 }
275
dcheng67be2b1f2014-10-27 21:47:29276 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50277 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34278 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09279 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34280 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09281 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50282 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34283 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09284 }
285
bnc33b8cef42014-11-19 17:30:38286 const char* GetAlternateProtocolFromParam() {
287 return
288 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
289 }
290
bncc958faa2015-07-31 18:14:52291 std::string GetAlternativeServiceHttpHeader() {
292 return std::string("Alt-Svc: ") + GetAlternateProtocolFromParam() +
293 "=\"www.example.com:443\"\r\n";
294 }
295
[email protected]8a0fc822013-06-27 20:52:43296 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38297 return std::string("Alternate-Protocol: 443:") +
bncc958faa2015-07-31 18:14:52298 GetAlternateProtocolFromParam() + "\r\n";
[email protected]8a0fc822013-06-27 20:52:43299 }
300
[email protected]202965992011-12-07 23:04:51301 // Either |write_failure| specifies a write failure or |read_failure|
302 // specifies a read failure when using a reused socket. In either case, the
303 // failure should cause the network transaction to resend the request, and the
304 // other argument should be NULL.
305 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
306 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52307
[email protected]a34f61ee2014-03-18 20:59:49308 // Either |write_failure| specifies a write failure or |read_failure|
309 // specifies a read failure when using a reused socket. In either case, the
310 // failure should cause the network transaction to resend the request, and the
311 // other argument should be NULL.
312 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10313 const MockRead* read_failure,
314 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49315
[email protected]5a60c8b2011-10-19 20:14:29316 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
317 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15318 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52319
[email protected]ff007e162009-05-23 09:13:15320 HttpRequestInfo request;
321 request.method = "GET";
bncce36dca22015-04-21 22:11:23322 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15323 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52324
vishal.b62985ca92015-04-17 08:45:51325 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07326 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07327 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27328 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41329 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27330
[email protected]5a60c8b2011-10-19 20:14:29331 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07332 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29333 }
initial.commit586acc5fe2008-07-26 22:42:52334
[email protected]49639fa2011-12-20 23:22:41335 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52336
eroman24bc6a12015-05-06 19:55:48337 EXPECT_TRUE(log.bound().IsCapturing());
[email protected]49639fa2011-12-20 23:22:41338 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15339 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52340
[email protected]ff007e162009-05-23 09:13:15341 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25342
343 // Even in the failure cases that use this function, connections are always
344 // successfully established before the error.
345 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
346 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
347
[email protected]ff007e162009-05-23 09:13:15348 if (out.rv != OK)
349 return out;
350
351 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50352 // Can't use ASSERT_* inside helper functions like this, so
353 // return an error.
[email protected]90499482013-06-01 00:39:50354 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50355 out.rv = ERR_UNEXPECTED;
356 return out;
357 }
[email protected]ff007e162009-05-23 09:13:15358 out.status_line = response->headers->GetStatusLine();
359
[email protected]80a09a82012-11-16 17:40:06360 EXPECT_EQ("127.0.0.1", response->socket_address.host());
361 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19362
[email protected]ff007e162009-05-23 09:13:15363 rv = ReadTransaction(trans.get(), &out.response_data);
364 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40365
mmenke43758e62015-05-04 21:09:46366 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40367 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39368 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40369 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12370 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39371 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40372 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39373 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
374 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15375
[email protected]f3da152d2012-06-02 01:00:57376 std::string line;
377 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
378 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
379
[email protected]79e1fd62013-06-20 06:50:04380 HttpRequestHeaders request_headers;
381 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
382 std::string value;
383 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23384 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04385 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
386 EXPECT_EQ("keep-alive", value);
387
388 std::string response_headers;
389 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23390 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04391 response_headers);
[email protected]3deb9a52010-11-11 00:24:40392
[email protected]b8015c42013-12-24 15:18:19393 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
ttuttle1f2d7e92015-04-28 16:17:47394 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47395 return out;
[email protected]ff007e162009-05-23 09:13:15396 }
initial.commit586acc5fe2008-07-26 22:42:52397
[email protected]5a60c8b2011-10-19 20:14:29398 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
399 size_t reads_count) {
400 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
401 StaticSocketDataProvider* data[] = { &reads };
402 return SimpleGetHelperForData(data, 1);
403 }
404
[email protected]b8015c42013-12-24 15:18:19405 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
406 int64 size = 0;
407 for (size_t i = 0; i < reads_count; ++i)
408 size += data_reads[i].data_len;
409 return size;
410 }
411
[email protected]ff007e162009-05-23 09:13:15412 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
413 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52414
[email protected]ff007e162009-05-23 09:13:15415 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07416
417 void BypassHostCacheOnRefreshHelper(int load_flags);
418
419 void CheckErrorIsPassedBack(int error, IoMode mode);
420
[email protected]4bd46222013-05-14 19:32:23421 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07422 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03423
424 // Original socket limits. Some tests set these. Safest to always restore
425 // them once each test has been run.
426 int old_max_group_sockets_;
427 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15428};
[email protected]231d5a32008-09-13 00:45:27429
bnc57685ae62015-03-10 21:27:20430INSTANTIATE_TEST_CASE_P(NextProto,
431 HttpNetworkTransactionTest,
432 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:43433 kProtoHTTP2));
[email protected]23e482282013-06-14 16:08:02434
[email protected]448d4ca52012-03-04 04:12:23435namespace {
436
[email protected]1826a402014-01-08 15:40:48437class BeforeNetworkStartHandler {
438 public:
439 explicit BeforeNetworkStartHandler(bool defer)
440 : defer_on_before_network_start_(defer),
441 observed_before_network_start_(false) {}
442
443 void OnBeforeNetworkStart(bool* defer) {
444 *defer = defer_on_before_network_start_;
445 observed_before_network_start_ = true;
446 }
447
448 bool observed_before_network_start() const {
449 return observed_before_network_start_;
450 }
451
452 private:
453 const bool defer_on_before_network_start_;
454 bool observed_before_network_start_;
455
456 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
457};
458
[email protected]597a1ab2014-06-26 08:12:27459class BeforeProxyHeadersSentHandler {
460 public:
461 BeforeProxyHeadersSentHandler()
462 : observed_before_proxy_headers_sent_(false) {}
463
[email protected]1252d42f2014-07-01 21:20:20464 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
465 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27466 observed_before_proxy_headers_sent_ = true;
467 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
468 }
469
470 bool observed_before_proxy_headers_sent() const {
471 return observed_before_proxy_headers_sent_;
472 }
473
474 std::string observed_proxy_server_uri() const {
475 return observed_proxy_server_uri_;
476 }
477
478 private:
479 bool observed_before_proxy_headers_sent_;
480 std::string observed_proxy_server_uri_;
481
482 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
483};
484
[email protected]15a5ccf82008-10-23 19:57:43485// Fill |str| with a long header list that consumes >= |size| bytes.
486void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51487 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19488 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
489 const int sizeof_row = strlen(row);
490 const int num_rows = static_cast<int>(
491 ceil(static_cast<float>(size) / sizeof_row));
492 const int sizeof_data = num_rows * sizeof_row;
493 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43494 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51495
[email protected]4ddaf2502008-10-23 18:26:19496 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43497 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19498}
499
thakis84dff942015-07-28 20:47:38500#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29501// Alternative functions that eliminate randomness and dependency on the local
502// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20503void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29504 static const uint8 bytes[] = {
505 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
506 };
507 static size_t current_byte = 0;
508 for (size_t i = 0; i < n; ++i) {
509 output[i] = bytes[current_byte++];
510 current_byte %= arraysize(bytes);
511 }
512}
513
[email protected]fe2bc6a2009-03-23 16:52:20514void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29515 static const uint8 bytes[] = {
516 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
517 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
518 };
519 static size_t current_byte = 0;
520 for (size_t i = 0; i < n; ++i) {
521 output[i] = bytes[current_byte++];
522 current_byte %= arraysize(bytes);
523 }
524}
525
[email protected]fe2bc6a2009-03-23 16:52:20526std::string MockGetHostName() {
527 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29528}
thakis84dff942015-07-28 20:47:38529#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29530
[email protected]e60e47a2010-07-14 03:37:18531template<typename ParentPool>
532class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31533 public:
[email protected]9e1bdd32011-02-03 21:48:34534 CaptureGroupNameSocketPool(HostResolver* host_resolver,
535 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18536
[email protected]d80a4322009-08-14 07:07:49537 const std::string last_group_name_received() const {
538 return last_group_name_;
539 }
540
dmichaeld6e570d2014-12-18 22:30:57541 int RequestSocket(const std::string& group_name,
542 const void* socket_params,
543 RequestPriority priority,
544 ClientSocketHandle* handle,
545 const CompletionCallback& callback,
546 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31547 last_group_name_ = group_name;
548 return ERR_IO_PENDING;
549 }
dmichaeld6e570d2014-12-18 22:30:57550 void CancelRequest(const std::string& group_name,
551 ClientSocketHandle* handle) override {}
552 void ReleaseSocket(const std::string& group_name,
553 scoped_ptr<StreamSocket> socket,
554 int id) override {}
555 void CloseIdleSockets() override {}
556 int IdleSocketCount() const override { return 0; }
557 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31558 return 0;
559 }
dmichaeld6e570d2014-12-18 22:30:57560 LoadState GetLoadState(const std::string& group_name,
561 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31562 return LOAD_STATE_IDLE;
563 }
dmichaeld6e570d2014-12-18 22:30:57564 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26565 return base::TimeDelta();
566 }
[email protected]d80a4322009-08-14 07:07:49567
568 private:
[email protected]04e5be32009-06-26 20:00:31569 std::string last_group_name_;
570};
571
[email protected]ab739042011-04-07 15:22:28572typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
573CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13574typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
575CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06576typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11577CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18578typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
579CaptureGroupNameSSLSocketPool;
580
rkaplowd90695c2015-03-25 22:12:41581template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18582CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34583 HostResolver* host_resolver,
584 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41585 : ParentPool(0, 0, host_resolver, NULL, NULL) {
586}
[email protected]e60e47a2010-07-14 03:37:18587
hashimoto0d3e4fb2015-01-09 05:02:50588template <>
[email protected]2df19bb2010-08-25 20:13:46589CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21590 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34591 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41592 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50593}
[email protected]2df19bb2010-08-25 20:13:46594
[email protected]007b3f82013-04-09 08:46:45595template <>
[email protected]e60e47a2010-07-14 03:37:18596CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21597 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34598 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45599 : SSLClientSocketPool(0,
600 0,
[email protected]007b3f82013-04-09 08:46:45601 cert_verifier,
602 NULL,
603 NULL,
[email protected]284303b62013-11-28 15:11:54604 NULL,
eranm6571b2b2014-12-03 15:53:23605 NULL,
[email protected]007b3f82013-04-09 08:46:45606 std::string(),
607 NULL,
608 NULL,
609 NULL,
610 NULL,
611 NULL,
[email protected]8e458552014-08-05 00:02:15612 NULL) {
613}
[email protected]2227c692010-05-04 15:36:11614
[email protected]231d5a32008-09-13 00:45:27615//-----------------------------------------------------------------------------
616
[email protected]79cb5c12011-09-12 13:12:04617// Helper functions for validating that AuthChallengeInfo's are correctly
618// configured for common cases.
619bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
620 if (!auth_challenge)
621 return false;
622 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23623 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04624 EXPECT_EQ("MyRealm1", auth_challenge->realm);
625 EXPECT_EQ("basic", auth_challenge->scheme);
626 return true;
627}
628
629bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
630 if (!auth_challenge)
631 return false;
632 EXPECT_TRUE(auth_challenge->is_proxy);
633 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
634 EXPECT_EQ("MyRealm1", auth_challenge->realm);
635 EXPECT_EQ("basic", auth_challenge->scheme);
636 return true;
637}
638
639bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
640 if (!auth_challenge)
641 return false;
642 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23643 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04644 EXPECT_EQ("digestive", auth_challenge->realm);
645 EXPECT_EQ("digest", auth_challenge->scheme);
646 return true;
647}
648
thakis84dff942015-07-28 20:47:38649#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04650bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
651 if (!auth_challenge)
652 return false;
653 EXPECT_FALSE(auth_challenge->is_proxy);
654 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
655 EXPECT_EQ(std::string(), auth_challenge->realm);
656 EXPECT_EQ("ntlm", auth_challenge->scheme);
657 return true;
658}
thakis84dff942015-07-28 20:47:38659#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04660
[email protected]448d4ca52012-03-04 04:12:23661} // namespace
662
[email protected]23e482282013-06-14 16:08:02663TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07664 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40665 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41666 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27667}
668
[email protected]23e482282013-06-14 16:08:02669TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27670 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35671 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
672 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06673 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27674 };
[email protected]31a2bfe2010-02-09 08:03:39675 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
676 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42677 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27678 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
679 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19680 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
681 EXPECT_EQ(reads_size, out.totalReceivedBytes);
ttuttle1f2d7e92015-04-28 16:17:47682 EXPECT_EQ(0u, out.connection_attempts.size());
[email protected]231d5a32008-09-13 00:45:27683}
684
685// Response with no status line.
[email protected]23e482282013-06-14 16:08:02686TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27687 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35688 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06689 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27690 };
[email protected]31a2bfe2010-02-09 08:03:39691 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
692 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42693 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27694 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
695 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19696 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
697 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27698}
699
700// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02701TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27702 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35703 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06704 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27705 };
[email protected]31a2bfe2010-02-09 08:03:39706 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
707 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42708 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27709 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
710 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19711 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
712 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27713}
714
715// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02716TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27717 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35718 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06719 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27720 };
[email protected]31a2bfe2010-02-09 08:03:39721 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
722 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42723 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27724 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
725 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19726 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
727 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27728}
729
730// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02731TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27732 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35733 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06734 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27735 };
[email protected]31a2bfe2010-02-09 08:03:39736 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
737 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42738 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25739 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
740 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19741 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
742 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27743}
744
745// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02746TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27747 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35748 MockRead("\n"),
749 MockRead("\n"),
750 MockRead("Q"),
751 MockRead("J"),
752 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06753 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27754 };
[email protected]31a2bfe2010-02-09 08:03:39755 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
756 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42757 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27758 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
759 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19760 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
761 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27762}
763
764// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02765TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27766 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35767 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06768 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27769 };
[email protected]31a2bfe2010-02-09 08:03:39770 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
771 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42772 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27773 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
774 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19775 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
776 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52777}
778
[email protected]f9d44aa2008-09-23 23:57:17779// Simulate a 204 response, lacking a Content-Length header, sent over a
780// persistent connection. The response should still terminate since a 204
781// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02782TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19783 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17784 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35785 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19786 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06787 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17788 };
[email protected]31a2bfe2010-02-09 08:03:39789 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
790 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42791 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17792 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
793 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19794 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
795 int64 response_size = reads_size - strlen(junk);
796 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17797}
798
[email protected]0877e3d2009-10-17 22:29:57799// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02800TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19801 std::string final_chunk = "0\r\n\r\n";
802 std::string extra_data = "HTTP/1.1 200 OK\r\n";
803 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57804 MockRead data_reads[] = {
805 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
806 MockRead("5\r\nHello\r\n"),
807 MockRead("1\r\n"),
808 MockRead(" \r\n"),
809 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19810 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06811 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57812 };
[email protected]31a2bfe2010-02-09 08:03:39813 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
814 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57815 EXPECT_EQ(OK, out.rv);
816 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
817 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19818 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
819 int64 response_size = reads_size - extra_data.size();
820 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57821}
822
[email protected]9fe44f52010-09-23 18:36:00823// Next tests deal with http://crbug.com/56344.
824
[email protected]23e482282013-06-14 16:08:02825TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00826 MultipleContentLengthHeadersNoTransferEncoding) {
827 MockRead data_reads[] = {
828 MockRead("HTTP/1.1 200 OK\r\n"),
829 MockRead("Content-Length: 10\r\n"),
830 MockRead("Content-Length: 5\r\n\r\n"),
831 };
832 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
833 arraysize(data_reads));
834 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
835}
836
[email protected]23e482282013-06-14 16:08:02837TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04838 DuplicateContentLengthHeadersNoTransferEncoding) {
839 MockRead data_reads[] = {
840 MockRead("HTTP/1.1 200 OK\r\n"),
841 MockRead("Content-Length: 5\r\n"),
842 MockRead("Content-Length: 5\r\n\r\n"),
843 MockRead("Hello"),
844 };
845 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
846 arraysize(data_reads));
847 EXPECT_EQ(OK, out.rv);
848 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
849 EXPECT_EQ("Hello", out.response_data);
850}
851
[email protected]23e482282013-06-14 16:08:02852TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04853 ComplexContentLengthHeadersNoTransferEncoding) {
854 // More than 2 dupes.
855 {
856 MockRead data_reads[] = {
857 MockRead("HTTP/1.1 200 OK\r\n"),
858 MockRead("Content-Length: 5\r\n"),
859 MockRead("Content-Length: 5\r\n"),
860 MockRead("Content-Length: 5\r\n\r\n"),
861 MockRead("Hello"),
862 };
863 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
864 arraysize(data_reads));
865 EXPECT_EQ(OK, out.rv);
866 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
867 EXPECT_EQ("Hello", out.response_data);
868 }
869 // HTTP/1.0
870 {
871 MockRead data_reads[] = {
872 MockRead("HTTP/1.0 200 OK\r\n"),
873 MockRead("Content-Length: 5\r\n"),
874 MockRead("Content-Length: 5\r\n"),
875 MockRead("Content-Length: 5\r\n\r\n"),
876 MockRead("Hello"),
877 };
878 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
879 arraysize(data_reads));
880 EXPECT_EQ(OK, out.rv);
881 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
882 EXPECT_EQ("Hello", out.response_data);
883 }
884 // 2 dupes and one mismatched.
885 {
886 MockRead data_reads[] = {
887 MockRead("HTTP/1.1 200 OK\r\n"),
888 MockRead("Content-Length: 10\r\n"),
889 MockRead("Content-Length: 10\r\n"),
890 MockRead("Content-Length: 5\r\n\r\n"),
891 };
892 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
893 arraysize(data_reads));
894 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
895 }
896}
897
[email protected]23e482282013-06-14 16:08:02898TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00899 MultipleContentLengthHeadersTransferEncoding) {
900 MockRead data_reads[] = {
901 MockRead("HTTP/1.1 200 OK\r\n"),
902 MockRead("Content-Length: 666\r\n"),
903 MockRead("Content-Length: 1337\r\n"),
904 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
905 MockRead("5\r\nHello\r\n"),
906 MockRead("1\r\n"),
907 MockRead(" \r\n"),
908 MockRead("5\r\nworld\r\n"),
909 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06910 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00911 };
912 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
913 arraysize(data_reads));
914 EXPECT_EQ(OK, out.rv);
915 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
916 EXPECT_EQ("Hello world", out.response_data);
917}
918
[email protected]1628fe92011-10-04 23:04:55919// Next tests deal with http://crbug.com/98895.
920
921// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02922TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55923 MockRead data_reads[] = {
924 MockRead("HTTP/1.1 200 OK\r\n"),
925 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"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.1 200 OK", out.status_line);
933 EXPECT_EQ("Hello", out.response_data);
934}
935
[email protected]54a9c6e52012-03-21 20:10:59936// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02937TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59938 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55939 MockRead data_reads[] = {
940 MockRead("HTTP/1.1 200 OK\r\n"),
941 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
942 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
943 MockRead("Content-Length: 5\r\n\r\n"),
944 MockRead("Hello"),
945 };
946 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
947 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59948 EXPECT_EQ(OK, out.rv);
949 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
950 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55951}
952
953// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02954TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55955 MockRead data_reads[] = {
956 MockRead("HTTP/1.1 200 OK\r\n"),
957 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
958 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
959 MockRead("Content-Length: 5\r\n\r\n"),
960 MockRead("Hello"),
961 };
962 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
963 arraysize(data_reads));
964 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
965}
966
[email protected]54a9c6e52012-03-21 20:10:59967// Checks that two identical Location headers result in no error.
968// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02969TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55970 MockRead data_reads[] = {
971 MockRead("HTTP/1.1 302 Redirect\r\n"),
972 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59973 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55974 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06975 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55976 };
977
978 HttpRequestInfo request;
979 request.method = "GET";
980 request.url = GURL("http://redirect.com/");
981 request.load_flags = 0;
982
[email protected]3fe8d2f82013-10-17 08:56:07983 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55984 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41985 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:55986
987 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07988 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55989
[email protected]49639fa2011-12-20 23:22:41990 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55991
[email protected]49639fa2011-12-20 23:22:41992 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55993 EXPECT_EQ(ERR_IO_PENDING, rv);
994
995 EXPECT_EQ(OK, callback.WaitForResult());
996
997 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50998 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55999 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1000 std::string url;
1001 EXPECT_TRUE(response->headers->IsRedirect(&url));
1002 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151003 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551004}
1005
[email protected]1628fe92011-10-04 23:04:551006// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021007TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551008 MockRead data_reads[] = {
1009 MockRead("HTTP/1.1 302 Redirect\r\n"),
1010 MockRead("Location: http://good.com/\r\n"),
1011 MockRead("Location: http://evil.com/\r\n"),
1012 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061013 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551014 };
1015 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1016 arraysize(data_reads));
1017 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1018}
1019
[email protected]ef0faf2e72009-03-05 23:27:231020// Do a request using the HEAD method. Verify that we don't try to read the
1021// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021022TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421023 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231024 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231025 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231026 request.load_flags = 0;
1027
[email protected]3fe8d2f82013-10-17 08:56:071028 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271029 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411030 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271031 BeforeProxyHeadersSentHandler proxy_headers_handler;
1032 trans->SetBeforeProxyHeadersSentCallback(
1033 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1034 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271035
[email protected]ef0faf2e72009-03-05 23:27:231036 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131037 MockWrite("HEAD / HTTP/1.1\r\n"
1038 "Host: www.example.org\r\n"
1039 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231040 };
1041 MockRead data_reads1[] = {
1042 MockRead("HTTP/1.1 404 Not Found\r\n"),
1043 MockRead("Server: Blah\r\n"),
1044 MockRead("Content-Length: 1234\r\n\r\n"),
1045
1046 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061047 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231048 };
1049
[email protected]31a2bfe2010-02-09 08:03:391050 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1051 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071052 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231053
[email protected]49639fa2011-12-20 23:22:411054 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231055
[email protected]49639fa2011-12-20 23:22:411056 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421057 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231058
1059 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421060 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231061
[email protected]1c773ea12009-04-28 19:58:421062 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501063 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231064
1065 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501066 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231067 EXPECT_EQ(1234, response->headers->GetContentLength());
1068 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151069 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271070 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231071
1072 std::string server_header;
1073 void* iter = NULL;
1074 bool has_server_header = response->headers->EnumerateHeader(
1075 &iter, "Server", &server_header);
1076 EXPECT_TRUE(has_server_header);
1077 EXPECT_EQ("Blah", server_header);
1078
1079 // Reading should give EOF right away, since there is no message body
1080 // (despite non-zero content-length).
1081 std::string response_data;
1082 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421083 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231084 EXPECT_EQ("", response_data);
1085}
1086
[email protected]23e482282013-06-14 16:08:021087TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071088 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521089
1090 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351091 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1092 MockRead("hello"),
1093 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1094 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061095 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521096 };
[email protected]31a2bfe2010-02-09 08:03:391097 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071098 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521099
[email protected]0b0bf032010-09-21 18:08:501100 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521101 "hello", "world"
1102 };
1103
1104 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421105 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521106 request.method = "GET";
bncce36dca22015-04-21 22:11:231107 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521108 request.load_flags = 0;
1109
[email protected]262eec82013-03-19 21:01:361110 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501111 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271112
[email protected]49639fa2011-12-20 23:22:411113 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521114
[email protected]49639fa2011-12-20 23:22:411115 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421116 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521117
1118 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421119 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521120
[email protected]1c773ea12009-04-28 19:58:421121 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501122 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521123
[email protected]90499482013-06-01 00:39:501124 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251125 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151126 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521127
1128 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571129 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421130 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251131 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521132 }
1133}
1134
[email protected]23e482282013-06-14 16:08:021135TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061136 ScopedVector<UploadElementReader> element_readers;
1137 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071138 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271139
[email protected]1c773ea12009-04-28 19:58:421140 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521141 request.method = "POST";
1142 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271143 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521144 request.load_flags = 0;
1145
[email protected]3fe8d2f82013-10-17 08:56:071146 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271147 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411148 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271149
initial.commit586acc5fe2008-07-26 22:42:521150 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351151 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1152 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1153 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061154 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521155 };
[email protected]31a2bfe2010-02-09 08:03:391156 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071157 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521158
[email protected]49639fa2011-12-20 23:22:411159 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521160
[email protected]49639fa2011-12-20 23:22:411161 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421162 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521163
1164 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421165 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521166
[email protected]1c773ea12009-04-28 19:58:421167 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501168 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521169
[email protected]90499482013-06-01 00:39:501170 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251171 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521172
1173 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571174 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421175 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251176 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521177}
1178
[email protected]3a2d3662009-03-27 03:49:141179// This test is almost the same as Ignores100 above, but the response contains
1180// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571181// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021182TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421183 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141184 request.method = "GET";
1185 request.url = GURL("http://www.foo.com/");
1186 request.load_flags = 0;
1187
[email protected]3fe8d2f82013-10-17 08:56:071188 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271189 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411190 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271191
[email protected]3a2d3662009-03-27 03:49:141192 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571193 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1194 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141195 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061196 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141197 };
[email protected]31a2bfe2010-02-09 08:03:391198 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071199 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141200
[email protected]49639fa2011-12-20 23:22:411201 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141202
[email protected]49639fa2011-12-20 23:22:411203 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421204 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141205
1206 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421207 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141208
[email protected]1c773ea12009-04-28 19:58:421209 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501210 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141211
[email protected]90499482013-06-01 00:39:501212 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141213 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1214
1215 std::string response_data;
1216 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421217 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141218 EXPECT_EQ("hello world", response_data);
1219}
1220
[email protected]23e482282013-06-14 16:08:021221TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081222 HttpRequestInfo request;
1223 request.method = "POST";
1224 request.url = GURL("http://www.foo.com/");
1225 request.load_flags = 0;
1226
1227 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1228 scoped_ptr<HttpTransaction> trans(
1229 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1230
1231 MockRead data_reads[] = {
1232 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1233 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381234 };
zmo9528c9f42015-08-04 22:12:081235 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1236 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381237
zmo9528c9f42015-08-04 22:12:081238 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381239
zmo9528c9f42015-08-04 22:12:081240 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1241 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381242
zmo9528c9f42015-08-04 22:12:081243 rv = callback.WaitForResult();
1244 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381245
zmo9528c9f42015-08-04 22:12:081246 std::string response_data;
1247 rv = ReadTransaction(trans.get(), &response_data);
1248 EXPECT_EQ(OK, rv);
1249 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381250}
1251
[email protected]23e482282013-06-14 16:08:021252TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381253 HttpRequestInfo request;
1254 request.method = "POST";
1255 request.url = GURL("http://www.foo.com/");
1256 request.load_flags = 0;
1257
[email protected]3fe8d2f82013-10-17 08:56:071258 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271259 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411260 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271261
[email protected]ee9410e72010-01-07 01:42:381262 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061263 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381264 };
[email protected]31a2bfe2010-02-09 08:03:391265 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071266 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381267
[email protected]49639fa2011-12-20 23:22:411268 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381269
[email protected]49639fa2011-12-20 23:22:411270 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381271 EXPECT_EQ(ERR_IO_PENDING, rv);
1272
1273 rv = callback.WaitForResult();
1274 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1275}
1276
[email protected]23e482282013-06-14 16:08:021277void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511278 const MockWrite* write_failure,
1279 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421280 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521281 request.method = "GET";
1282 request.url = GURL("http://www.foo.com/");
1283 request.load_flags = 0;
1284
vishal.b62985ca92015-04-17 08:45:511285 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071286 session_deps_.net_log = &net_log;
1287 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271288
[email protected]202965992011-12-07 23:04:511289 // Written data for successfully sending both requests.
1290 MockWrite data1_writes[] = {
1291 MockWrite("GET / HTTP/1.1\r\n"
1292 "Host: www.foo.com\r\n"
1293 "Connection: keep-alive\r\n\r\n"),
1294 MockWrite("GET / HTTP/1.1\r\n"
1295 "Host: www.foo.com\r\n"
1296 "Connection: keep-alive\r\n\r\n")
1297 };
1298
1299 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521300 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351301 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1302 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061303 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521304 };
[email protected]202965992011-12-07 23:04:511305
1306 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491307 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511308 data1_writes[1] = *write_failure;
1309 } else {
1310 ASSERT_TRUE(read_failure);
1311 data1_reads[2] = *read_failure;
1312 }
1313
1314 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1315 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071316 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521317
1318 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351319 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1320 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061321 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521322 };
[email protected]31a2bfe2010-02-09 08:03:391323 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071324 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521325
thestig9d3bb0c2015-01-24 00:49:511326 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521327 "hello", "world"
1328 };
1329
[email protected]58e32bb2013-01-21 18:23:251330 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521331 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411332 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521333
[email protected]262eec82013-03-19 21:01:361334 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501335 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521336
[email protected]49639fa2011-12-20 23:22:411337 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421338 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521339
1340 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421341 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521342
[email protected]58e32bb2013-01-21 18:23:251343 LoadTimingInfo load_timing_info;
1344 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1345 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1346 if (i == 0) {
1347 first_socket_log_id = load_timing_info.socket_log_id;
1348 } else {
1349 // The second request should be using a new socket.
1350 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1351 }
1352
[email protected]1c773ea12009-04-28 19:58:421353 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501354 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521355
[email protected]90499482013-06-01 00:39:501356 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251357 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521358
1359 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571360 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421361 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251362 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521363 }
1364}
[email protected]3d2a59b2008-09-26 19:44:251365
[email protected]a34f61ee2014-03-18 20:59:491366void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1367 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101368 const MockRead* read_failure,
1369 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491370 HttpRequestInfo request;
1371 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101372 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491373 request.load_flags = 0;
1374
vishal.b62985ca92015-04-17 08:45:511375 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491376 session_deps_.net_log = &net_log;
1377 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1378
[email protected]09356c652014-03-25 15:36:101379 SSLSocketDataProvider ssl1(ASYNC, OK);
1380 SSLSocketDataProvider ssl2(ASYNC, OK);
1381 if (use_spdy) {
1382 ssl1.SetNextProto(GetParam());
1383 ssl2.SetNextProto(GetParam());
1384 }
1385 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1386 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491387
[email protected]09356c652014-03-25 15:36:101388 // SPDY versions of the request and response.
1389 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1390 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1391 scoped_ptr<SpdyFrame> spdy_response(
1392 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1393 scoped_ptr<SpdyFrame> spdy_data(
1394 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491395
[email protected]09356c652014-03-25 15:36:101396 // HTTP/1.1 versions of the request and response.
1397 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1398 "Host: www.foo.com\r\n"
1399 "Connection: keep-alive\r\n\r\n";
1400 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1401 const char kHttpData[] = "hello";
1402
1403 std::vector<MockRead> data1_reads;
1404 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491405 if (write_failure) {
1406 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101407 data1_writes.push_back(*write_failure);
1408 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491409 } else {
1410 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101411 if (use_spdy) {
1412 data1_writes.push_back(CreateMockWrite(*spdy_request));
1413 } else {
1414 data1_writes.push_back(MockWrite(kHttpRequest));
1415 }
1416 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491417 }
1418
[email protected]09356c652014-03-25 15:36:101419 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1420 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491421 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1422
[email protected]09356c652014-03-25 15:36:101423 std::vector<MockRead> data2_reads;
1424 std::vector<MockWrite> data2_writes;
1425
1426 if (use_spdy) {
1427 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1428
1429 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1430 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1431 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1432 } else {
1433 data2_writes.push_back(
1434 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1435
1436 data2_reads.push_back(
1437 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1438 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1439 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1440 }
rch8e6c6c42015-05-01 14:05:131441 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1442 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491443 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1444
1445 // Preconnect a socket.
ttuttle859dc7a2015-04-23 19:42:291446 SSLConfig ssl_config;
[email protected]a34f61ee2014-03-18 20:59:491447 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231448 session->GetNextProtos(&ssl_config.next_protos);
mmenked1205bd2015-07-15 22:26:351449 session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
1450 ssl_config);
[email protected]a34f61ee2014-03-18 20:59:491451 // Wait for the preconnect to complete.
1452 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1453 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101454 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491455
1456 // Make the request.
1457 TestCompletionCallback callback;
1458
1459 scoped_ptr<HttpTransaction> trans(
1460 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1461
1462 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1463 EXPECT_EQ(ERR_IO_PENDING, rv);
1464
1465 rv = callback.WaitForResult();
1466 EXPECT_EQ(OK, rv);
1467
1468 LoadTimingInfo load_timing_info;
1469 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101470 TestLoadTimingNotReused(
1471 load_timing_info,
1472 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491473
1474 const HttpResponseInfo* response = trans->GetResponseInfo();
1475 ASSERT_TRUE(response != NULL);
1476
1477 EXPECT_TRUE(response->headers.get() != NULL);
1478 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1479
1480 std::string response_data;
1481 rv = ReadTransaction(trans.get(), &response_data);
1482 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101483 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491484}
1485
[email protected]23e482282013-06-14 16:08:021486TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231487 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061488 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511489 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1490}
1491
[email protected]23e482282013-06-14 16:08:021492TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061493 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511494 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251495}
1496
[email protected]23e482282013-06-14 16:08:021497TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061498 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511499 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251500}
1501
[email protected]d58ceea82014-06-04 10:55:541502// Make sure that on a 408 response (Request Timeout), the request is retried,
1503// if the socket was a reused keep alive socket.
1504TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1505 MockRead read_failure(SYNCHRONOUS,
1506 "HTTP/1.1 408 Request Timeout\r\n"
1507 "Connection: Keep-Alive\r\n"
1508 "Content-Length: 6\r\n\r\n"
1509 "Pickle");
1510 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1511}
1512
[email protected]a34f61ee2014-03-18 20:59:491513TEST_P(HttpNetworkTransactionTest,
1514 PreconnectErrorNotConnectedOnWrite) {
1515 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101516 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491517}
1518
1519TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1520 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101521 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491522}
1523
1524TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1525 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101526 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1527}
1528
1529TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1530 MockRead read_failure(ASYNC, OK); // EOF
1531 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1532}
1533
[email protected]d58ceea82014-06-04 10:55:541534// Make sure that on a 408 response (Request Timeout), the request is retried,
1535// if the socket was a preconnected (UNUSED_IDLE) socket.
1536TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1537 MockRead read_failure(SYNCHRONOUS,
1538 "HTTP/1.1 408 Request Timeout\r\n"
1539 "Connection: Keep-Alive\r\n"
1540 "Content-Length: 6\r\n\r\n"
1541 "Pickle");
1542 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1543 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1544}
1545
[email protected]09356c652014-03-25 15:36:101546TEST_P(HttpNetworkTransactionTest,
1547 SpdyPreconnectErrorNotConnectedOnWrite) {
1548 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1549 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1550}
1551
1552TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1553 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1554 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1555}
1556
1557TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1558 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1559 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1560}
1561
1562TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1563 MockRead read_failure(ASYNC, OK); // EOF
1564 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491565}
1566
[email protected]23e482282013-06-14 16:08:021567TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421568 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251569 request.method = "GET";
bncce36dca22015-04-21 22:11:231570 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251571 request.load_flags = 0;
1572
[email protected]3fe8d2f82013-10-17 08:56:071573 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271574 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411575 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271576
[email protected]3d2a59b2008-09-26 19:44:251577 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061578 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351579 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1580 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061581 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251582 };
[email protected]31a2bfe2010-02-09 08:03:391583 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071584 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251585
[email protected]49639fa2011-12-20 23:22:411586 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251587
[email protected]49639fa2011-12-20 23:22:411588 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421589 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251590
1591 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421592 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251593}
1594
1595// What do various browsers do when the server closes a non-keepalive
1596// connection without sending any response header or body?
1597//
1598// IE7: error page
1599// Safari 3.1.2 (Windows): error page
1600// Firefox 3.0.1: blank page
1601// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421602// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1603// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021604TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251605 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061606 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351607 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1608 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061609 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251610 };
[email protected]31a2bfe2010-02-09 08:03:391611 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1612 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421613 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251614}
[email protected]038e9a32008-10-08 22:40:161615
[email protected]1826a402014-01-08 15:40:481616// Test that network access can be deferred and resumed.
1617TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1618 HttpRequestInfo request;
1619 request.method = "GET";
bncce36dca22015-04-21 22:11:231620 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481621 request.load_flags = 0;
1622
1623 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1624 scoped_ptr<HttpTransaction> trans(
1625 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1626
1627 // Defer on OnBeforeNetworkStart.
1628 BeforeNetworkStartHandler net_start_handler(true); // defer
1629 trans->SetBeforeNetworkStartCallback(
1630 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1631 base::Unretained(&net_start_handler)));
1632
1633 MockRead data_reads[] = {
1634 MockRead("HTTP/1.0 200 OK\r\n"),
1635 MockRead("Content-Length: 5\r\n\r\n"),
1636 MockRead("hello"),
1637 MockRead(SYNCHRONOUS, 0),
1638 };
1639 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1640 session_deps_.socket_factory->AddSocketDataProvider(&data);
1641
1642 TestCompletionCallback callback;
1643
1644 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1645 EXPECT_EQ(ERR_IO_PENDING, rv);
1646 base::MessageLoop::current()->RunUntilIdle();
1647
1648 // Should have deferred for network start.
1649 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1650 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481651
1652 trans->ResumeNetworkStart();
1653 rv = callback.WaitForResult();
1654 EXPECT_EQ(OK, rv);
1655 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1656
1657 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1658 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1659 if (rv == ERR_IO_PENDING)
1660 rv = callback.WaitForResult();
1661 EXPECT_EQ(5, rv);
1662 trans.reset();
1663}
1664
1665// Test that network use can be deferred and canceled.
1666TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1667 HttpRequestInfo request;
1668 request.method = "GET";
bncce36dca22015-04-21 22:11:231669 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481670 request.load_flags = 0;
1671
1672 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1673 scoped_ptr<HttpTransaction> trans(
1674 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1675
1676 // Defer on OnBeforeNetworkStart.
1677 BeforeNetworkStartHandler net_start_handler(true); // defer
1678 trans->SetBeforeNetworkStartCallback(
1679 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1680 base::Unretained(&net_start_handler)));
1681
1682 TestCompletionCallback callback;
1683
1684 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1685 EXPECT_EQ(ERR_IO_PENDING, rv);
1686 base::MessageLoop::current()->RunUntilIdle();
1687
1688 // Should have deferred for network start.
1689 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1690 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481691}
1692
[email protected]7a5378b2012-11-04 03:25:171693// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1694// tests. There was a bug causing HttpNetworkTransaction to hang in the
1695// destructor in such situations.
1696// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021697TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171698 HttpRequestInfo request;
1699 request.method = "GET";
bncce36dca22015-04-21 22:11:231700 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171701 request.load_flags = 0;
1702
[email protected]bb88e1d32013-05-03 23:11:071703 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361704 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501705 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171706
1707 MockRead data_reads[] = {
1708 MockRead("HTTP/1.0 200 OK\r\n"),
1709 MockRead("Connection: keep-alive\r\n"),
1710 MockRead("Content-Length: 100\r\n\r\n"),
1711 MockRead("hello"),
1712 MockRead(SYNCHRONOUS, 0),
1713 };
1714 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071715 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171716
1717 TestCompletionCallback callback;
1718
1719 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1720 EXPECT_EQ(ERR_IO_PENDING, rv);
1721
1722 rv = callback.WaitForResult();
1723 EXPECT_EQ(OK, rv);
1724
1725 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501726 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171727 if (rv == ERR_IO_PENDING)
1728 rv = callback.WaitForResult();
1729 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501730 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171731 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1732
1733 trans.reset();
[email protected]2da659e2013-05-23 20:51:341734 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171735 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1736}
1737
[email protected]23e482282013-06-14 16:08:021738TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171739 HttpRequestInfo request;
1740 request.method = "GET";
bncce36dca22015-04-21 22:11:231741 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171742 request.load_flags = 0;
1743
[email protected]bb88e1d32013-05-03 23:11:071744 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361745 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501746 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171747
1748 MockRead data_reads[] = {
1749 MockRead("HTTP/1.0 200 OK\r\n"),
1750 MockRead("Connection: keep-alive\r\n"),
1751 MockRead("Content-Length: 100\r\n\r\n"),
1752 MockRead(SYNCHRONOUS, 0),
1753 };
1754 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071755 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171756
1757 TestCompletionCallback callback;
1758
1759 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1760 EXPECT_EQ(ERR_IO_PENDING, rv);
1761
1762 rv = callback.WaitForResult();
1763 EXPECT_EQ(OK, rv);
1764
1765 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501766 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171767 if (rv == ERR_IO_PENDING)
1768 rv = callback.WaitForResult();
1769 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1770
1771 trans.reset();
[email protected]2da659e2013-05-23 20:51:341772 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171773 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1774}
1775
[email protected]0b0bf032010-09-21 18:08:501776// Test that we correctly reuse a keep-alive connection after not explicitly
1777// reading the body.
[email protected]23e482282013-06-14 16:08:021778TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131779 HttpRequestInfo request;
1780 request.method = "GET";
1781 request.url = GURL("http://www.foo.com/");
1782 request.load_flags = 0;
1783
vishal.b62985ca92015-04-17 08:45:511784 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071785 session_deps_.net_log = &net_log;
1786 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271787
[email protected]0b0bf032010-09-21 18:08:501788 // Note that because all these reads happen in the same
1789 // StaticSocketDataProvider, it shows that the same socket is being reused for
1790 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131791 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501792 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1793 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131794 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501795 MockRead("HTTP/1.1 302 Found\r\n"
1796 "Content-Length: 0\r\n\r\n"),
1797 MockRead("HTTP/1.1 302 Found\r\n"
1798 "Content-Length: 5\r\n\r\n"
1799 "hello"),
1800 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1801 "Content-Length: 0\r\n\r\n"),
1802 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1803 "Content-Length: 5\r\n\r\n"
1804 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131805 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1806 MockRead("hello"),
1807 };
1808 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071809 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131810
1811 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061812 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131813 };
1814 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071815 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131816
[email protected]0b0bf032010-09-21 18:08:501817 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1818 std::string response_lines[kNumUnreadBodies];
1819
[email protected]58e32bb2013-01-21 18:23:251820 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501821 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411822 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131823
[email protected]262eec82013-03-19 21:01:361824 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501825 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131826
[email protected]49639fa2011-12-20 23:22:411827 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131828 EXPECT_EQ(ERR_IO_PENDING, rv);
1829
1830 rv = callback.WaitForResult();
1831 EXPECT_EQ(OK, rv);
1832
[email protected]58e32bb2013-01-21 18:23:251833 LoadTimingInfo load_timing_info;
1834 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1835 if (i == 0) {
1836 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1837 first_socket_log_id = load_timing_info.socket_log_id;
1838 } else {
1839 TestLoadTimingReused(load_timing_info);
1840 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1841 }
1842
[email protected]fc31d6a42010-06-24 18:05:131843 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501844 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131845
[email protected]90499482013-06-01 00:39:501846 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501847 response_lines[i] = response->headers->GetStatusLine();
1848
1849 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131850 }
[email protected]0b0bf032010-09-21 18:08:501851
1852 const char* const kStatusLines[] = {
1853 "HTTP/1.1 204 No Content",
1854 "HTTP/1.1 205 Reset Content",
1855 "HTTP/1.1 304 Not Modified",
1856 "HTTP/1.1 302 Found",
1857 "HTTP/1.1 302 Found",
1858 "HTTP/1.1 301 Moved Permanently",
1859 "HTTP/1.1 301 Moved Permanently",
1860 };
1861
mostynb91e0da982015-01-20 19:17:271862 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1863 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501864
1865 for (int i = 0; i < kNumUnreadBodies; ++i)
1866 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1867
[email protected]49639fa2011-12-20 23:22:411868 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361869 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501870 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411871 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501872 EXPECT_EQ(ERR_IO_PENDING, rv);
1873 rv = callback.WaitForResult();
1874 EXPECT_EQ(OK, rv);
1875 const HttpResponseInfo* response = trans->GetResponseInfo();
1876 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501877 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501878 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1879 std::string response_data;
1880 rv = ReadTransaction(trans.get(), &response_data);
1881 EXPECT_EQ(OK, rv);
1882 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131883}
1884
[email protected]038e9a32008-10-08 22:40:161885// Test the request-challenge-retry sequence for basic auth.
1886// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021887TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421888 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161889 request.method = "GET";
bncce36dca22015-04-21 22:11:231890 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161891 request.load_flags = 0;
1892
vishal.b62985ca92015-04-17 08:45:511893 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071894 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071895 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271896 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411897 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271898
[email protected]f9ee6b52008-11-08 06:46:231899 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231900 MockWrite(
1901 "GET / HTTP/1.1\r\n"
1902 "Host: www.example.org\r\n"
1903 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231904 };
1905
[email protected]038e9a32008-10-08 22:40:161906 MockRead data_reads1[] = {
1907 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1908 // Give a couple authenticate options (only the middle one is actually
1909 // supported).
[email protected]22927ad2009-09-21 19:56:191910 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161911 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1912 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1913 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1914 // Large content-length -- won't matter, as connection will be reset.
1915 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061916 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161917 };
1918
1919 // After calling trans->RestartWithAuth(), this is the request we should
1920 // be issuing -- the final header line contains the credentials.
1921 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231922 MockWrite(
1923 "GET / HTTP/1.1\r\n"
1924 "Host: www.example.org\r\n"
1925 "Connection: keep-alive\r\n"
1926 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161927 };
1928
1929 // Lastly, the server responds with the actual content.
1930 MockRead data_reads2[] = {
1931 MockRead("HTTP/1.0 200 OK\r\n"),
1932 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1933 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061934 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161935 };
1936
[email protected]31a2bfe2010-02-09 08:03:391937 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1938 data_writes1, arraysize(data_writes1));
1939 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1940 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071941 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1942 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161943
[email protected]49639fa2011-12-20 23:22:411944 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161945
[email protected]49639fa2011-12-20 23:22:411946 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421947 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161948
1949 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421950 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161951
[email protected]58e32bb2013-01-21 18:23:251952 LoadTimingInfo load_timing_info1;
1953 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1954 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1955
[email protected]b8015c42013-12-24 15:18:191956 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1957 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1958
[email protected]1c773ea12009-04-28 19:58:421959 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501960 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041961 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161962
[email protected]49639fa2011-12-20 23:22:411963 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161964
[email protected]49639fa2011-12-20 23:22:411965 rv = trans->RestartWithAuth(
1966 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421967 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161968
1969 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421970 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161971
[email protected]58e32bb2013-01-21 18:23:251972 LoadTimingInfo load_timing_info2;
1973 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1974 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1975 // The load timing after restart should have a new socket ID, and times after
1976 // those of the first load timing.
1977 EXPECT_LE(load_timing_info1.receive_headers_end,
1978 load_timing_info2.connect_timing.connect_start);
1979 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1980
[email protected]b8015c42013-12-24 15:18:191981 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1982 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1983
[email protected]038e9a32008-10-08 22:40:161984 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501985 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161986 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1987 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161988}
1989
[email protected]23e482282013-06-14 16:08:021990TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461991 HttpRequestInfo request;
1992 request.method = "GET";
bncce36dca22015-04-21 22:11:231993 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:291994 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:461995
[email protected]3fe8d2f82013-10-17 08:56:071996 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271997 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411998 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271999
[email protected]861fcd52009-08-26 02:33:462000 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232001 MockWrite(
2002 "GET / HTTP/1.1\r\n"
2003 "Host: www.example.org\r\n"
2004 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462005 };
2006
2007 MockRead data_reads[] = {
2008 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2009 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2010 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2011 // Large content-length -- won't matter, as connection will be reset.
2012 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062013 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462014 };
2015
[email protected]31a2bfe2010-02-09 08:03:392016 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2017 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072018 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412019 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462020
[email protected]49639fa2011-12-20 23:22:412021 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462022 EXPECT_EQ(ERR_IO_PENDING, rv);
2023
2024 rv = callback.WaitForResult();
2025 EXPECT_EQ(0, rv);
2026
[email protected]b8015c42013-12-24 15:18:192027 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2028 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2029
[email protected]861fcd52009-08-26 02:33:462030 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502031 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462032 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2033}
2034
[email protected]2d2697f92009-02-18 21:00:322035// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2036// connection.
[email protected]23e482282013-06-14 16:08:022037TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422038 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322039 request.method = "GET";
bncce36dca22015-04-21 22:11:232040 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322041 request.load_flags = 0;
2042
vishal.b62985ca92015-04-17 08:45:512043 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072044 session_deps_.net_log = &log;
2045 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272046
[email protected]2d2697f92009-02-18 21:00:322047 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232048 MockWrite(
2049 "GET / HTTP/1.1\r\n"
2050 "Host: www.example.org\r\n"
2051 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322052
bncce36dca22015-04-21 22:11:232053 // After calling trans->RestartWithAuth(), this is the request we should
2054 // be issuing -- the final header line contains the credentials.
2055 MockWrite(
2056 "GET / HTTP/1.1\r\n"
2057 "Host: www.example.org\r\n"
2058 "Connection: keep-alive\r\n"
2059 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322060 };
2061
2062 MockRead data_reads1[] = {
2063 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2064 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2065 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2066 MockRead("Content-Length: 14\r\n\r\n"),
2067 MockRead("Unauthorized\r\n"),
2068
2069 // Lastly, the server responds with the actual content.
2070 MockRead("HTTP/1.1 200 OK\r\n"),
2071 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502072 MockRead("Content-Length: 5\r\n\r\n"),
2073 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322074 };
2075
[email protected]2d0a4f92011-05-05 16:38:462076 // If there is a regression where we disconnect a Keep-Alive
2077 // connection during an auth roundtrip, we'll end up reading this.
2078 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062079 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462080 };
2081
[email protected]31a2bfe2010-02-09 08:03:392082 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2083 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462084 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2085 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072086 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2087 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322088
[email protected]49639fa2011-12-20 23:22:412089 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322090
[email protected]262eec82013-03-19 21:01:362091 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502092 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412093 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422094 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322095
2096 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422097 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322098
[email protected]58e32bb2013-01-21 18:23:252099 LoadTimingInfo load_timing_info1;
2100 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2101 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2102
[email protected]1c773ea12009-04-28 19:58:422103 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502104 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042105 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322106
[email protected]49639fa2011-12-20 23:22:412107 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322108
[email protected]49639fa2011-12-20 23:22:412109 rv = trans->RestartWithAuth(
2110 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422111 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322112
2113 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422114 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322115
[email protected]58e32bb2013-01-21 18:23:252116 LoadTimingInfo load_timing_info2;
2117 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2118 TestLoadTimingReused(load_timing_info2);
2119 // The load timing after restart should have the same socket ID, and times
2120 // those of the first load timing.
2121 EXPECT_LE(load_timing_info1.receive_headers_end,
2122 load_timing_info2.send_start);
2123 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2124
[email protected]2d2697f92009-02-18 21:00:322125 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502126 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322127 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502128 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192129
2130 std::string response_data;
2131 rv = ReadTransaction(trans.get(), &response_data);
2132 EXPECT_EQ(OK, rv);
2133 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2134 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322135}
2136
2137// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2138// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022139TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422140 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322141 request.method = "GET";
bncce36dca22015-04-21 22:11:232142 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322143 request.load_flags = 0;
2144
[email protected]bb88e1d32013-05-03 23:11:072145 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272146
[email protected]2d2697f92009-02-18 21:00:322147 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232148 MockWrite(
2149 "GET / HTTP/1.1\r\n"
2150 "Host: www.example.org\r\n"
2151 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322152
bncce36dca22015-04-21 22:11:232153 // After calling trans->RestartWithAuth(), this is the request we should
2154 // be issuing -- the final header line contains the credentials.
2155 MockWrite(
2156 "GET / HTTP/1.1\r\n"
2157 "Host: www.example.org\r\n"
2158 "Connection: keep-alive\r\n"
2159 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322160 };
2161
[email protected]2d2697f92009-02-18 21:00:322162 MockRead data_reads1[] = {
2163 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2164 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312165 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322166
2167 // Lastly, the server responds with the actual content.
2168 MockRead("HTTP/1.1 200 OK\r\n"),
2169 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502170 MockRead("Content-Length: 5\r\n\r\n"),
2171 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322172 };
2173
[email protected]2d0a4f92011-05-05 16:38:462174 // An incorrect reconnect would cause this to be read.
2175 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062176 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462177 };
2178
[email protected]31a2bfe2010-02-09 08:03:392179 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2180 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462181 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2182 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072183 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2184 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322185
[email protected]49639fa2011-12-20 23:22:412186 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322187
[email protected]262eec82013-03-19 21:01:362188 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502189 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412190 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422191 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322192
2193 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422194 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322195
[email protected]1c773ea12009-04-28 19:58:422196 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502197 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042198 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322199
[email protected]49639fa2011-12-20 23:22:412200 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322201
[email protected]49639fa2011-12-20 23:22:412202 rv = trans->RestartWithAuth(
2203 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422204 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322205
2206 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422207 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322208
2209 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502210 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322211 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502212 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322213}
2214
2215// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2216// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022217TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422218 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322219 request.method = "GET";
bncce36dca22015-04-21 22:11:232220 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322221 request.load_flags = 0;
2222
[email protected]bb88e1d32013-05-03 23:11:072223 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272224
[email protected]2d2697f92009-02-18 21:00:322225 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232226 MockWrite(
2227 "GET / HTTP/1.1\r\n"
2228 "Host: www.example.org\r\n"
2229 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322230
bncce36dca22015-04-21 22:11:232231 // After calling trans->RestartWithAuth(), this is the request we should
2232 // be issuing -- the final header line contains the credentials.
2233 MockWrite(
2234 "GET / HTTP/1.1\r\n"
2235 "Host: www.example.org\r\n"
2236 "Connection: keep-alive\r\n"
2237 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322238 };
2239
2240 // Respond with 5 kb of response body.
2241 std::string large_body_string("Unauthorized");
2242 large_body_string.append(5 * 1024, ' ');
2243 large_body_string.append("\r\n");
2244
2245 MockRead data_reads1[] = {
2246 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2247 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2248 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2249 // 5134 = 12 + 5 * 1024 + 2
2250 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062251 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322252
2253 // Lastly, the server responds with the actual content.
2254 MockRead("HTTP/1.1 200 OK\r\n"),
2255 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502256 MockRead("Content-Length: 5\r\n\r\n"),
2257 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322258 };
2259
[email protected]2d0a4f92011-05-05 16:38:462260 // An incorrect reconnect would cause this to be read.
2261 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062262 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462263 };
2264
[email protected]31a2bfe2010-02-09 08:03:392265 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2266 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462267 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2268 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072269 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2270 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322271
[email protected]49639fa2011-12-20 23:22:412272 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322273
[email protected]262eec82013-03-19 21:01:362274 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502275 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412276 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422277 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322278
2279 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422280 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322281
[email protected]1c773ea12009-04-28 19:58:422282 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502283 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042284 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322285
[email protected]49639fa2011-12-20 23:22:412286 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322287
[email protected]49639fa2011-12-20 23:22:412288 rv = trans->RestartWithAuth(
2289 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422290 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322291
2292 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422293 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322294
2295 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502296 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322297 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502298 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322299}
2300
2301// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312302// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022303TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312304 HttpRequestInfo request;
2305 request.method = "GET";
bncce36dca22015-04-21 22:11:232306 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312307 request.load_flags = 0;
2308
[email protected]bb88e1d32013-05-03 23:11:072309 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272310
[email protected]11203f012009-11-12 23:02:312311 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232312 MockWrite(
2313 "GET / HTTP/1.1\r\n"
2314 "Host: www.example.org\r\n"
2315 "Connection: keep-alive\r\n\r\n"),
2316 // This simulates the seemingly successful write to a closed connection
2317 // if the bug is not fixed.
2318 MockWrite(
2319 "GET / HTTP/1.1\r\n"
2320 "Host: www.example.org\r\n"
2321 "Connection: keep-alive\r\n"
2322 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312323 };
2324
2325 MockRead data_reads1[] = {
2326 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2327 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2328 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2329 MockRead("Content-Length: 14\r\n\r\n"),
2330 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062331 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312332 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062333 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312334 };
2335
2336 // After calling trans->RestartWithAuth(), this is the request we should
2337 // be issuing -- the final header line contains the credentials.
2338 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232339 MockWrite(
2340 "GET / HTTP/1.1\r\n"
2341 "Host: www.example.org\r\n"
2342 "Connection: keep-alive\r\n"
2343 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312344 };
2345
2346 // Lastly, the server responds with the actual content.
2347 MockRead data_reads2[] = {
2348 MockRead("HTTP/1.1 200 OK\r\n"),
2349 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502350 MockRead("Content-Length: 5\r\n\r\n"),
2351 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312352 };
2353
[email protected]31a2bfe2010-02-09 08:03:392354 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2355 data_writes1, arraysize(data_writes1));
2356 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2357 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072358 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2359 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312360
[email protected]49639fa2011-12-20 23:22:412361 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312362
[email protected]262eec82013-03-19 21:01:362363 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412365 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312366 EXPECT_EQ(ERR_IO_PENDING, rv);
2367
2368 rv = callback1.WaitForResult();
2369 EXPECT_EQ(OK, rv);
2370
2371 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502372 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042373 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312374
[email protected]49639fa2011-12-20 23:22:412375 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312376
[email protected]49639fa2011-12-20 23:22:412377 rv = trans->RestartWithAuth(
2378 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312379 EXPECT_EQ(ERR_IO_PENDING, rv);
2380
2381 rv = callback2.WaitForResult();
2382 EXPECT_EQ(OK, rv);
2383
2384 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502385 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312386 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502387 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312388}
2389
[email protected]394816e92010-08-03 07:38:592390// Test the request-challenge-retry sequence for basic auth, over a connection
2391// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012392TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2393 HttpRequestInfo request;
2394 request.method = "GET";
bncce36dca22015-04-21 22:11:232395 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012396 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292397 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012398
2399 // Configure against proxy server "myproxy:70".
2400 session_deps_.proxy_service.reset(
2401 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512402 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012403 session_deps_.net_log = log.bound().net_log();
2404 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2405
2406 // Since we have proxy, should try to establish tunnel.
2407 MockWrite data_writes1[] = {
mmenkee0b5c882015-08-26 20:29:112408 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2409 "Host: www.example.org\r\n"
2410 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012411 };
2412
mmenkee0b5c882015-08-26 20:29:112413 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012414 // connection.
2415 MockRead data_reads1[] = {
2416 // No credentials.
2417 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2418 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112419 };
ttuttle34f63b52015-03-05 04:33:012420
mmenkee0b5c882015-08-26 20:29:112421 // Since the first connection couldn't be reused, need to establish another
2422 // once given credentials.
2423 MockWrite data_writes2[] = {
2424 // After calling trans->RestartWithAuth(), this is the request we should
2425 // be issuing -- the final header line contains the credentials.
2426 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2427 "Host: www.example.org\r\n"
2428 "Proxy-Connection: keep-alive\r\n"
2429 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2430
2431 MockWrite("GET / HTTP/1.1\r\n"
2432 "Host: www.example.org\r\n"
2433 "Connection: keep-alive\r\n\r\n"),
2434 };
2435
2436 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012437 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2438
2439 MockRead("HTTP/1.1 200 OK\r\n"),
2440 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2441 MockRead("Content-Length: 5\r\n\r\n"),
2442 MockRead(SYNCHRONOUS, "hello"),
2443 };
2444
2445 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2446 data_writes1, arraysize(data_writes1));
2447 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee0b5c882015-08-26 20:29:112448 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2449 data_writes2, arraysize(data_writes2));
2450 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012451 SSLSocketDataProvider ssl(ASYNC, OK);
2452 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2453
2454 TestCompletionCallback callback1;
2455
2456 scoped_ptr<HttpTransaction> trans(
2457 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2458
2459 int rv = trans->Start(&request, callback1.callback(), log.bound());
2460 EXPECT_EQ(ERR_IO_PENDING, rv);
2461
2462 rv = callback1.WaitForResult();
2463 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462464 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012465 log.GetEntries(&entries);
2466 size_t pos = ExpectLogContainsSomewhere(
2467 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2468 NetLog::PHASE_NONE);
2469 ExpectLogContainsSomewhere(
2470 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2471 NetLog::PHASE_NONE);
2472
2473 const HttpResponseInfo* response = trans->GetResponseInfo();
2474 ASSERT_TRUE(response != NULL);
2475 EXPECT_FALSE(response->headers->IsKeepAlive());
2476 ASSERT_FALSE(response->headers.get() == NULL);
2477 EXPECT_EQ(407, response->headers->response_code());
2478 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2479 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2480
2481 LoadTimingInfo load_timing_info;
2482 // CONNECT requests and responses are handled at the connect job level, so
2483 // the transaction does not yet have a connection.
2484 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2485
2486 TestCompletionCallback callback2;
2487
2488 rv =
2489 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2490 EXPECT_EQ(ERR_IO_PENDING, rv);
2491
2492 rv = callback2.WaitForResult();
2493 EXPECT_EQ(OK, rv);
2494
2495 response = trans->GetResponseInfo();
2496 ASSERT_TRUE(response != NULL);
2497
2498 EXPECT_TRUE(response->headers->IsKeepAlive());
2499 EXPECT_EQ(200, response->headers->response_code());
2500 EXPECT_EQ(5, response->headers->GetContentLength());
2501 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2502
2503 // The password prompt info should not be set.
2504 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2505
2506 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2507 TestLoadTimingNotReusedWithPac(load_timing_info,
2508 CONNECT_TIMING_HAS_SSL_TIMES);
2509
2510 trans.reset();
2511 session->CloseAllConnections();
2512}
2513
2514// Test the request-challenge-retry sequence for basic auth, over a connection
2515// that requires a restart when setting up an SSL tunnel.
2516TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592517 HttpRequestInfo request;
2518 request.method = "GET";
bncce36dca22015-04-21 22:11:232519 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592520 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292521 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592522
[email protected]cb9bf6ca2011-01-28 13:15:272523 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072524 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202525 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512526 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072527 session_deps_.net_log = log.bound().net_log();
2528 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272529
[email protected]394816e92010-08-03 07:38:592530 // Since we have proxy, should try to establish tunnel.
2531 MockWrite data_writes1[] = {
mmenkee0b5c882015-08-26 20:29:112532 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2533 "Host: www.example.org\r\n"
2534 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592535 };
2536
mmenkee0b5c882015-08-26 20:29:112537 // The proxy responds to the connect with a 407, using a non-persistent
[email protected]394816e92010-08-03 07:38:592538 // connection.
2539 MockRead data_reads1[] = {
mmenkee0b5c882015-08-26 20:29:112540 // No credentials.
2541 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2542 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2543 MockRead("Proxy-Connection: close\r\n\r\n"),
2544 };
[email protected]394816e92010-08-03 07:38:592545
mmenkee0b5c882015-08-26 20:29:112546 MockWrite data_writes2[] = {
2547 // After calling trans->RestartWithAuth(), this is the request we should
2548 // be issuing -- the final header line contains the credentials.
2549 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2550 "Host: www.example.org\r\n"
2551 "Proxy-Connection: keep-alive\r\n"
2552 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592553
mmenkee0b5c882015-08-26 20:29:112554 MockWrite("GET / HTTP/1.1\r\n"
2555 "Host: www.example.org\r\n"
2556 "Connection: keep-alive\r\n\r\n"),
2557 };
2558
2559 MockRead data_reads2[] = {
2560 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2561
2562 MockRead("HTTP/1.1 200 OK\r\n"),
2563 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2564 MockRead("Content-Length: 5\r\n\r\n"),
2565 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592566 };
2567
2568 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2569 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072570 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee0b5c882015-08-26 20:29:112571 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2572 data_writes2, arraysize(data_writes2));
2573 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:062574 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072575 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592576
[email protected]49639fa2011-12-20 23:22:412577 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592578
[email protected]262eec82013-03-19 21:01:362579 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502580 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502581
[email protected]49639fa2011-12-20 23:22:412582 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592583 EXPECT_EQ(ERR_IO_PENDING, rv);
2584
2585 rv = callback1.WaitForResult();
2586 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462587 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402588 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592589 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402590 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592591 NetLog::PHASE_NONE);
2592 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402593 entries, pos,
[email protected]394816e92010-08-03 07:38:592594 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2595 NetLog::PHASE_NONE);
2596
2597 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502598 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012599 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502600 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592601 EXPECT_EQ(407, response->headers->response_code());
2602 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042603 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592604
[email protected]029c83b62013-01-24 05:28:202605 LoadTimingInfo load_timing_info;
2606 // CONNECT requests and responses are handled at the connect job level, so
2607 // the transaction does not yet have a connection.
2608 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2609
[email protected]49639fa2011-12-20 23:22:412610 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592611
[email protected]49639fa2011-12-20 23:22:412612 rv = trans->RestartWithAuth(
2613 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592614 EXPECT_EQ(ERR_IO_PENDING, rv);
2615
2616 rv = callback2.WaitForResult();
2617 EXPECT_EQ(OK, rv);
2618
2619 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502620 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592621
2622 EXPECT_TRUE(response->headers->IsKeepAlive());
2623 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502624 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592625 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2626
2627 // The password prompt info should not be set.
2628 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502629
[email protected]029c83b62013-01-24 05:28:202630 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2631 TestLoadTimingNotReusedWithPac(load_timing_info,
2632 CONNECT_TIMING_HAS_SSL_TIMES);
2633
[email protected]0b0bf032010-09-21 18:08:502634 trans.reset();
[email protected]102e27c2011-02-23 01:01:312635 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592636}
2637
[email protected]11203f012009-11-12 23:02:312638// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012639// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2640TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2641 HttpRequestInfo request;
2642 request.method = "GET";
bncce36dca22015-04-21 22:11:232643 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012644 // Ensure that proxy authentication is attempted even
2645 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292646 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012647
2648 // Configure against proxy server "myproxy:70".
2649 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512650 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012651 session_deps_.net_log = log.bound().net_log();
2652 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2653
2654 scoped_ptr<HttpTransaction> trans(
2655 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2656
2657 // Since we have proxy, should try to establish tunnel.
2658 MockWrite data_writes1[] = {
2659 MockWrite(
bncce36dca22015-04-21 22:11:232660 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2661 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012662 "Proxy-Connection: keep-alive\r\n\r\n"),
2663
2664 // After calling trans->RestartWithAuth(), this is the request we should
2665 // be issuing -- the final header line contains the credentials.
2666 MockWrite(
bncce36dca22015-04-21 22:11:232667 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2668 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012669 "Proxy-Connection: keep-alive\r\n"
2670 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2671 };
2672
2673 // The proxy responds to the connect with a 407, using a persistent
2674 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2675 MockRead data_reads1[] = {
2676 // No credentials.
2677 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2678 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2679 MockRead("Proxy-Connection: keep-alive\r\n"),
2680 MockRead("Content-Length: 10\r\n\r\n"),
2681 MockRead("0123456789"),
2682
2683 // Wrong credentials (wrong password).
2684 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2685 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2686 MockRead("Proxy-Connection: keep-alive\r\n"),
2687 MockRead("Content-Length: 10\r\n\r\n"),
2688 // No response body because the test stops reading here.
2689 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2690 };
2691
2692 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2693 data_writes1, arraysize(data_writes1));
2694 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2695
2696 TestCompletionCallback callback1;
2697
2698 int rv = trans->Start(&request, callback1.callback(), log.bound());
2699 EXPECT_EQ(ERR_IO_PENDING, rv);
2700
2701 rv = callback1.WaitForResult();
2702 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462703 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012704 log.GetEntries(&entries);
2705 size_t pos = ExpectLogContainsSomewhere(
2706 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2707 NetLog::PHASE_NONE);
2708 ExpectLogContainsSomewhere(
2709 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2710 NetLog::PHASE_NONE);
2711
2712 const HttpResponseInfo* response = trans->GetResponseInfo();
2713 ASSERT_TRUE(response);
2714 ASSERT_TRUE(response->headers);
2715 EXPECT_TRUE(response->headers->IsKeepAlive());
2716 EXPECT_EQ(407, response->headers->response_code());
2717 EXPECT_EQ(10, response->headers->GetContentLength());
2718 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2719 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2720
2721 TestCompletionCallback callback2;
2722
2723 // Wrong password (should be "bar").
2724 rv =
2725 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2726 EXPECT_EQ(ERR_IO_PENDING, rv);
2727
2728 rv = callback2.WaitForResult();
2729 EXPECT_EQ(OK, rv);
2730
2731 response = trans->GetResponseInfo();
2732 ASSERT_TRUE(response);
2733 ASSERT_TRUE(response->headers);
2734 EXPECT_TRUE(response->headers->IsKeepAlive());
2735 EXPECT_EQ(407, response->headers->response_code());
2736 EXPECT_EQ(10, response->headers->GetContentLength());
2737 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2738 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2739
2740 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2741 // out of scope.
2742 session->CloseAllConnections();
2743}
2744
2745// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2746// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2747TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272748 HttpRequestInfo request;
2749 request.method = "GET";
bncce36dca22015-04-21 22:11:232750 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272751 // Ensure that proxy authentication is attempted even
2752 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292753 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272754
[email protected]2d2697f92009-02-18 21:00:322755 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072756 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512757 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072758 session_deps_.net_log = log.bound().net_log();
2759 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322760
[email protected]262eec82013-03-19 21:01:362761 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502762 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322763
[email protected]2d2697f92009-02-18 21:00:322764 // Since we have proxy, should try to establish tunnel.
2765 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232766 MockWrite(
2767 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2768 "Host: www.example.org\r\n"
2769 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322770
bncce36dca22015-04-21 22:11:232771 // After calling trans->RestartWithAuth(), this is the request we should
2772 // be issuing -- the final header line contains the credentials.
2773 MockWrite(
2774 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2775 "Host: www.example.org\r\n"
2776 "Proxy-Connection: keep-alive\r\n"
2777 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322778 };
2779
2780 // The proxy responds to the connect with a 407, using a persistent
2781 // connection.
2782 MockRead data_reads1[] = {
2783 // No credentials.
2784 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2785 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2786 MockRead("Content-Length: 10\r\n\r\n"),
2787 MockRead("0123456789"),
2788
2789 // Wrong credentials (wrong password).
2790 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2791 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2792 MockRead("Content-Length: 10\r\n\r\n"),
2793 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062794 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322795 };
2796
[email protected]31a2bfe2010-02-09 08:03:392797 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2798 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072799 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322800
[email protected]49639fa2011-12-20 23:22:412801 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322802
[email protected]49639fa2011-12-20 23:22:412803 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422804 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322805
2806 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422807 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462808 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402809 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392810 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402811 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392812 NetLog::PHASE_NONE);
2813 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402814 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392815 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2816 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322817
[email protected]1c773ea12009-04-28 19:58:422818 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242819 ASSERT_TRUE(response);
2820 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322821 EXPECT_TRUE(response->headers->IsKeepAlive());
2822 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012823 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422824 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042825 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322826
[email protected]49639fa2011-12-20 23:22:412827 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322828
2829 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412830 rv = trans->RestartWithAuth(
2831 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422832 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322833
2834 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422835 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322836
2837 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242838 ASSERT_TRUE(response);
2839 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322840 EXPECT_TRUE(response->headers->IsKeepAlive());
2841 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012842 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422843 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042844 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132845
[email protected]e60e47a2010-07-14 03:37:182846 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2847 // out of scope.
[email protected]102e27c2011-02-23 01:01:312848 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322849}
2850
mmenkee0b5c882015-08-26 20:29:112851// Test the case a proxy closes a socket while the challenge body is being
2852// drained.
2853TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
2854 HttpRequestInfo request;
2855 request.method = "GET";
2856 request.url = GURL("https://www.example.org/");
2857 // Ensure that proxy authentication is attempted even
2858 // when the no authentication data flag is set.
2859 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
2860
2861 // Configure against proxy server "myproxy:70".
2862 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2863 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2864
2865 scoped_ptr<HttpTransaction> trans(
2866 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2867
2868 // Since we have proxy, should try to establish tunnel.
2869 MockWrite data_writes1[] = {
2870 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2871 "Host: www.example.org\r\n"
2872 "Proxy-Connection: keep-alive\r\n\r\n"),
2873 };
2874
2875 // The proxy responds to the connect with a 407, using a persistent
2876 // connection.
2877 MockRead data_reads1[] = {
2878 // No credentials.
2879 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2880 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2881 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
2882 // Server hands up in the middle of the body.
2883 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
2884 };
2885
2886 MockWrite data_writes2[] = {
2887 // After calling trans->RestartWithAuth(), this is the request we should
2888 // be issuing -- the final header line contains the credentials.
2889 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2890 "Host: www.example.org\r\n"
2891 "Proxy-Connection: keep-alive\r\n"
2892 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2893
2894 MockWrite("GET / HTTP/1.1\r\n"
2895 "Host: www.example.org\r\n"
2896 "Connection: keep-alive\r\n\r\n"),
2897 };
2898
2899 MockRead data_reads2[] = {
2900 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2901
2902 MockRead("HTTP/1.1 200 OK\r\n"),
2903 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2904 MockRead("Content-Length: 5\r\n\r\n"),
2905 MockRead(SYNCHRONOUS, "hello"),
2906 };
2907
2908 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2909 data_writes1, arraysize(data_writes1));
2910 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2911 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2912 data_writes2, arraysize(data_writes2));
2913 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2914 SSLSocketDataProvider ssl(ASYNC, OK);
2915 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2916
2917 TestCompletionCallback callback;
2918
2919 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2920 EXPECT_EQ(OK, callback.GetResult(rv));
2921
2922 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_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2928
2929 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
2930 EXPECT_EQ(OK, callback.GetResult(rv));
2931
2932 response = trans->GetResponseInfo();
2933 ASSERT_TRUE(response);
2934 ASSERT_TRUE(response->headers);
2935 EXPECT_TRUE(response->headers->IsKeepAlive());
2936 EXPECT_EQ(200, response->headers->response_code());
2937 std::string body;
2938 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
2939 EXPECT_EQ("hello", body);
2940}
2941
[email protected]a8e9b162009-03-12 00:06:442942// Test that we don't read the response body when we fail to establish a tunnel,
2943// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022944TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272945 HttpRequestInfo request;
2946 request.method = "GET";
bncce36dca22015-04-21 22:11:232947 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272948 request.load_flags = 0;
2949
[email protected]a8e9b162009-03-12 00:06:442950 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072951 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442952
[email protected]bb88e1d32013-05-03 23:11:072953 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442954
[email protected]262eec82013-03-19 21:01:362955 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502956 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442957
[email protected]a8e9b162009-03-12 00:06:442958 // Since we have proxy, should try to establish tunnel.
2959 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232960 MockWrite(
2961 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2962 "Host: www.example.org\r\n"
2963 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442964 };
2965
2966 // The proxy responds to the connect with a 407.
2967 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:242968 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2969 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2970 MockRead("Content-Length: 10\r\n\r\n"),
2971 MockRead("0123456789"), // Should not be reached.
2972 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:442973 };
2974
[email protected]31a2bfe2010-02-09 08:03:392975 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2976 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072977 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442978
[email protected]49639fa2011-12-20 23:22:412979 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442980
[email protected]49639fa2011-12-20 23:22:412981 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422982 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442983
2984 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422985 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442986
[email protected]1c773ea12009-04-28 19:58:422987 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242988 ASSERT_TRUE(response);
2989 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:442990 EXPECT_TRUE(response->headers->IsKeepAlive());
2991 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:422992 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442993
2994 std::string response_data;
2995 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422996 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182997
2998 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312999 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443000}
3001
ttuttle7933c112015-01-06 00:55:243002// Test that we don't pass extraneous headers from the proxy's response to the
3003// caller when the proxy responds to CONNECT with 407.
3004TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3005 HttpRequestInfo request;
3006 request.method = "GET";
bncce36dca22015-04-21 22:11:233007 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243008 request.load_flags = 0;
3009
3010 // Configure against proxy server "myproxy:70".
3011 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3012
3013 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3014
3015 scoped_ptr<HttpTransaction> trans(
3016 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3017
3018 // Since we have proxy, should try to establish tunnel.
3019 MockWrite data_writes[] = {
3020 MockWrite(
bncce36dca22015-04-21 22:11:233021 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3022 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:243023 "Proxy-Connection: keep-alive\r\n\r\n"),
3024 };
3025
3026 // The proxy responds to the connect with a 407.
3027 MockRead data_reads[] = {
3028 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3029 MockRead("X-Foo: bar\r\n"),
3030 MockRead("Set-Cookie: foo=bar\r\n"),
3031 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3032 MockRead("Content-Length: 10\r\n\r\n"),
3033 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
3034 };
3035
3036 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3037 arraysize(data_writes));
3038 session_deps_.socket_factory->AddSocketDataProvider(&data);
3039
3040 TestCompletionCallback callback;
3041
3042 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3043 EXPECT_EQ(ERR_IO_PENDING, rv);
3044
3045 rv = callback.WaitForResult();
3046 EXPECT_EQ(OK, rv);
3047
3048 const HttpResponseInfo* response = trans->GetResponseInfo();
3049 ASSERT_TRUE(response);
3050 ASSERT_TRUE(response->headers);
3051 EXPECT_TRUE(response->headers->IsKeepAlive());
3052 EXPECT_EQ(407, response->headers->response_code());
3053 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3054 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3055 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3056
3057 std::string response_data;
3058 rv = ReadTransaction(trans.get(), &response_data);
3059 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3060
3061 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3062 session->CloseAllConnections();
3063}
3064
[email protected]8fdbcd22010-05-05 02:54:523065// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3066// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023067TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523068 HttpRequestInfo request;
3069 request.method = "GET";
bncce36dca22015-04-21 22:11:233070 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523071 request.load_flags = 0;
3072
[email protected]cb9bf6ca2011-01-28 13:15:273073 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:073074 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273075 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413076 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273077
[email protected]8fdbcd22010-05-05 02:54:523078 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233079 MockWrite(
3080 "GET / HTTP/1.1\r\n"
3081 "Host: www.example.org\r\n"
3082 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523083 };
3084
3085 MockRead data_reads1[] = {
3086 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3087 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3088 // Large content-length -- won't matter, as connection will be reset.
3089 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063090 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523091 };
3092
3093 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3094 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073095 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523096
[email protected]49639fa2011-12-20 23:22:413097 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523098
[email protected]49639fa2011-12-20 23:22:413099 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523100 EXPECT_EQ(ERR_IO_PENDING, rv);
3101
3102 rv = callback.WaitForResult();
3103 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3104}
3105
[email protected]7a67a8152010-11-05 18:31:103106// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3107// through a non-authenticating proxy. The request should fail with
3108// ERR_UNEXPECTED_PROXY_AUTH.
3109// Note that it is impossible to detect if an HTTP server returns a 407 through
3110// a non-authenticating proxy - there is nothing to indicate whether the
3111// response came from the proxy or the server, so it is treated as if the proxy
3112// issued the challenge.
[email protected]23e482282013-06-14 16:08:023113TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233114 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273115 HttpRequestInfo request;
3116 request.method = "GET";
bncce36dca22015-04-21 22:11:233117 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273118
[email protected]bb88e1d32013-05-03 23:11:073119 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513120 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073121 session_deps_.net_log = log.bound().net_log();
3122 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103123
[email protected]7a67a8152010-11-05 18:31:103124 // Since we have proxy, should try to establish tunnel.
3125 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233126 MockWrite(
3127 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3128 "Host: www.example.org\r\n"
3129 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103130
bncce36dca22015-04-21 22:11:233131 MockWrite(
3132 "GET / HTTP/1.1\r\n"
3133 "Host: www.example.org\r\n"
3134 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103135 };
3136
3137 MockRead data_reads1[] = {
3138 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3139
3140 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3141 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3142 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063143 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103144 };
3145
3146 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3147 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073148 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063149 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073150 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103151
[email protected]49639fa2011-12-20 23:22:413152 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103153
[email protected]262eec82013-03-19 21:01:363154 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503155 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103156
[email protected]49639fa2011-12-20 23:22:413157 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103158 EXPECT_EQ(ERR_IO_PENDING, rv);
3159
3160 rv = callback1.WaitForResult();
3161 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463162 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403163 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103164 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403165 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103166 NetLog::PHASE_NONE);
3167 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403168 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103169 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3170 NetLog::PHASE_NONE);
3171}
[email protected]2df19bb2010-08-25 20:13:463172
[email protected]029c83b62013-01-24 05:28:203173// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023174TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203175 HttpRequestInfo request1;
3176 request1.method = "GET";
bncce36dca22015-04-21 22:11:233177 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203178
3179 HttpRequestInfo request2;
3180 request2.method = "GET";
bncce36dca22015-04-21 22:11:233181 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203182
3183 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073184 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203185 ProxyService::CreateFixed("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513186 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073187 session_deps_.net_log = log.bound().net_log();
3188 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203189
3190 // Since we have proxy, should try to establish tunnel.
3191 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233192 MockWrite(
3193 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3194 "Host: www.example.org\r\n"
3195 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203196
bncce36dca22015-04-21 22:11:233197 MockWrite(
3198 "GET /1 HTTP/1.1\r\n"
3199 "Host: www.example.org\r\n"
3200 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203201
bncce36dca22015-04-21 22:11:233202 MockWrite(
3203 "GET /2 HTTP/1.1\r\n"
3204 "Host: www.example.org\r\n"
3205 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203206 };
3207
3208 // The proxy responds to the connect with a 407, using a persistent
3209 // connection.
3210 MockRead data_reads1[] = {
3211 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3212
3213 MockRead("HTTP/1.1 200 OK\r\n"),
3214 MockRead("Content-Length: 1\r\n\r\n"),
3215 MockRead(SYNCHRONOUS, "1"),
3216
3217 MockRead("HTTP/1.1 200 OK\r\n"),
3218 MockRead("Content-Length: 2\r\n\r\n"),
3219 MockRead(SYNCHRONOUS, "22"),
3220 };
3221
3222 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3223 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073224 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203225 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073226 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203227
3228 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363229 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503230 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203231
3232 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3233 EXPECT_EQ(ERR_IO_PENDING, rv);
3234
3235 rv = callback1.WaitForResult();
3236 EXPECT_EQ(OK, rv);
3237
3238 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3239 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503240 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203241 EXPECT_EQ(1, response1->headers->GetContentLength());
3242
3243 LoadTimingInfo load_timing_info1;
3244 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3245 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3246
3247 trans1.reset();
3248
3249 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363250 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503251 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203252
3253 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3254 EXPECT_EQ(ERR_IO_PENDING, rv);
3255
3256 rv = callback2.WaitForResult();
3257 EXPECT_EQ(OK, rv);
3258
3259 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3260 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503261 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203262 EXPECT_EQ(2, response2->headers->GetContentLength());
3263
3264 LoadTimingInfo load_timing_info2;
3265 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3266 TestLoadTimingReused(load_timing_info2);
3267
3268 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3269
3270 trans2.reset();
3271 session->CloseAllConnections();
3272}
3273
3274// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023275TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203276 HttpRequestInfo request1;
3277 request1.method = "GET";
bncce36dca22015-04-21 22:11:233278 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203279
3280 HttpRequestInfo request2;
3281 request2.method = "GET";
bncce36dca22015-04-21 22:11:233282 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203283
3284 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073285 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203286 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513287 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073288 session_deps_.net_log = log.bound().net_log();
3289 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203290
3291 // Since we have proxy, should try to establish tunnel.
3292 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233293 MockWrite(
3294 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3295 "Host: www.example.org\r\n"
3296 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203297
bncce36dca22015-04-21 22:11:233298 MockWrite(
3299 "GET /1 HTTP/1.1\r\n"
3300 "Host: www.example.org\r\n"
3301 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203302
bncce36dca22015-04-21 22:11:233303 MockWrite(
3304 "GET /2 HTTP/1.1\r\n"
3305 "Host: www.example.org\r\n"
3306 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203307 };
3308
3309 // The proxy responds to the connect with a 407, using a persistent
3310 // connection.
3311 MockRead data_reads1[] = {
3312 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3313
3314 MockRead("HTTP/1.1 200 OK\r\n"),
3315 MockRead("Content-Length: 1\r\n\r\n"),
3316 MockRead(SYNCHRONOUS, "1"),
3317
3318 MockRead("HTTP/1.1 200 OK\r\n"),
3319 MockRead("Content-Length: 2\r\n\r\n"),
3320 MockRead(SYNCHRONOUS, "22"),
3321 };
3322
3323 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3324 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203326 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203328
3329 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363330 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503331 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203332
3333 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3334 EXPECT_EQ(ERR_IO_PENDING, rv);
3335
3336 rv = callback1.WaitForResult();
3337 EXPECT_EQ(OK, rv);
3338
3339 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3340 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503341 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203342 EXPECT_EQ(1, response1->headers->GetContentLength());
3343
3344 LoadTimingInfo load_timing_info1;
3345 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3346 TestLoadTimingNotReusedWithPac(load_timing_info1,
3347 CONNECT_TIMING_HAS_SSL_TIMES);
3348
3349 trans1.reset();
3350
3351 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363352 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503353 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203354
3355 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3356 EXPECT_EQ(ERR_IO_PENDING, rv);
3357
3358 rv = callback2.WaitForResult();
3359 EXPECT_EQ(OK, rv);
3360
3361 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3362 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503363 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203364 EXPECT_EQ(2, response2->headers->GetContentLength());
3365
3366 LoadTimingInfo load_timing_info2;
3367 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3368 TestLoadTimingReusedWithPac(load_timing_info2);
3369
3370 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3371
3372 trans2.reset();
3373 session->CloseAllConnections();
3374}
3375
[email protected]2df19bb2010-08-25 20:13:463376// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023377TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273378 HttpRequestInfo request;
3379 request.method = "GET";
bncce36dca22015-04-21 22:11:233380 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273381
[email protected]2df19bb2010-08-25 20:13:463382 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073383 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113384 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513385 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073386 session_deps_.net_log = log.bound().net_log();
3387 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463388
[email protected]2df19bb2010-08-25 20:13:463389 // Since we have proxy, should use full url
3390 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233391 MockWrite(
3392 "GET http://www.example.org/ HTTP/1.1\r\n"
3393 "Host: www.example.org\r\n"
3394 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463395 };
3396
3397 MockRead data_reads1[] = {
3398 MockRead("HTTP/1.1 200 OK\r\n"),
3399 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3400 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063401 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463402 };
3403
3404 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3405 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073406 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063407 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073408 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463409
[email protected]49639fa2011-12-20 23:22:413410 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463411
[email protected]262eec82013-03-19 21:01:363412 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503413 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503414
[email protected]49639fa2011-12-20 23:22:413415 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463416 EXPECT_EQ(ERR_IO_PENDING, rv);
3417
3418 rv = callback1.WaitForResult();
3419 EXPECT_EQ(OK, rv);
3420
[email protected]58e32bb2013-01-21 18:23:253421 LoadTimingInfo load_timing_info;
3422 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3423 TestLoadTimingNotReused(load_timing_info,
3424 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3425
[email protected]2df19bb2010-08-25 20:13:463426 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503427 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463428
3429 EXPECT_TRUE(response->headers->IsKeepAlive());
3430 EXPECT_EQ(200, response->headers->response_code());
3431 EXPECT_EQ(100, response->headers->GetContentLength());
3432 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3433
3434 // The password prompt info should not be set.
3435 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3436}
3437
[email protected]7642b5ae2010-09-01 20:55:173438// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023439TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273440 HttpRequestInfo request;
3441 request.method = "GET";
bncce36dca22015-04-21 22:11:233442 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273443 request.load_flags = 0;
3444
[email protected]7642b5ae2010-09-01 20:55:173445 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073446 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113447 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513448 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073449 session_deps_.net_log = log.bound().net_log();
3450 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173451
bncce36dca22015-04-21 22:11:233452 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463453 scoped_ptr<SpdyFrame> req(
3454 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133455 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:173456
[email protected]23e482282013-06-14 16:08:023457 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3458 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173459 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133460 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:173461 };
3462
rch8e6c6c42015-05-01 14:05:133463 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3464 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073465 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173466
[email protected]8ddf8322012-02-23 18:08:063467 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023468 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073469 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173470
[email protected]49639fa2011-12-20 23:22:413471 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173472
[email protected]262eec82013-03-19 21:01:363473 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503474 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503475
[email protected]49639fa2011-12-20 23:22:413476 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173477 EXPECT_EQ(ERR_IO_PENDING, rv);
3478
3479 rv = callback1.WaitForResult();
3480 EXPECT_EQ(OK, rv);
3481
[email protected]58e32bb2013-01-21 18:23:253482 LoadTimingInfo load_timing_info;
3483 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3484 TestLoadTimingNotReused(load_timing_info,
3485 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3486
[email protected]7642b5ae2010-09-01 20:55:173487 const HttpResponseInfo* response = trans->GetResponseInfo();
3488 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503489 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173490 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3491
3492 std::string response_data;
3493 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233494 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173495}
3496
[email protected]1c173852014-06-19 12:51:503497// Verifies that a session which races and wins against the owning transaction
3498// (completing prior to host resolution), doesn't fail the transaction.
3499// Regression test for crbug.com/334413.
3500TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3501 HttpRequestInfo request;
3502 request.method = "GET";
bncce36dca22015-04-21 22:11:233503 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:503504 request.load_flags = 0;
3505
3506 // Configure SPDY proxy server "proxy:70".
3507 session_deps_.proxy_service.reset(
3508 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513509 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:503510 session_deps_.net_log = log.bound().net_log();
3511 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3512
bncce36dca22015-04-21 22:11:233513 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:503514 scoped_ptr<SpdyFrame> req(
3515 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133516 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:503517
3518 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3519 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3520 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133521 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:503522 };
3523
rch8e6c6c42015-05-01 14:05:133524 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3525 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:503526 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3527
3528 SSLSocketDataProvider ssl(ASYNC, OK);
3529 ssl.SetNextProto(GetParam());
3530 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3531
3532 TestCompletionCallback callback1;
3533
3534 scoped_ptr<HttpTransaction> trans(
3535 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3536
3537 // Stall the hostname resolution begun by the transaction.
3538 session_deps_.host_resolver->set_synchronous_mode(false);
3539 session_deps_.host_resolver->set_ondemand_mode(true);
3540
3541 int rv = trans->Start(&request, callback1.callback(), log.bound());
3542 EXPECT_EQ(ERR_IO_PENDING, rv);
3543
3544 // Race a session to the proxy, which completes first.
3545 session_deps_.host_resolver->set_ondemand_mode(false);
3546 SpdySessionKey key(
3547 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3548 base::WeakPtr<SpdySession> spdy_session =
3549 CreateSecureSpdySession(session, key, log.bound());
3550
3551 // Unstall the resolution begun by the transaction.
3552 session_deps_.host_resolver->set_ondemand_mode(true);
3553 session_deps_.host_resolver->ResolveAllPending();
3554
3555 EXPECT_FALSE(callback1.have_result());
3556 rv = callback1.WaitForResult();
3557 EXPECT_EQ(OK, rv);
3558
3559 const HttpResponseInfo* response = trans->GetResponseInfo();
3560 ASSERT_TRUE(response != NULL);
3561 ASSERT_TRUE(response->headers.get() != NULL);
3562 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3563
3564 std::string response_data;
3565 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3566 EXPECT_EQ(kUploadData, response_data);
3567}
3568
[email protected]dc7bd1c52010-11-12 00:01:133569// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023570TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273571 HttpRequestInfo request;
3572 request.method = "GET";
bncce36dca22015-04-21 22:11:233573 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273574 request.load_flags = 0;
3575
[email protected]79cb5c12011-09-12 13:12:043576 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073577 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043578 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513579 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073580 session_deps_.net_log = log.bound().net_log();
3581 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133582
[email protected]dc7bd1c52010-11-12 00:01:133583 // The first request will be a bare GET, the second request will be a
3584 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193585 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463586 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133587 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463588 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133589 };
[email protected]ff98d7f02012-03-22 21:44:193590 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463591 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3592 arraysize(kExtraAuthorizationHeaders) / 2,
3593 false,
3594 3,
3595 LOWEST,
3596 false));
[email protected]dc7bd1c52010-11-12 00:01:133597 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133598 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:133599 };
3600
3601 // The first response is a 407 proxy authentication challenge, and the second
3602 // response will be a 200 response since the second request includes a valid
3603 // Authorization header.
3604 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463605 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133606 };
[email protected]ff98d7f02012-03-22 21:44:193607 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023608 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133609 "407 Proxy Authentication Required",
3610 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3611 1));
[email protected]ff98d7f02012-03-22 21:44:193612 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023613 spdy_util_.ConstructSpdyBodyFrame(1, true));
3614 scoped_ptr<SpdyFrame> resp_data(
3615 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3616 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133617 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133618 CreateMockRead(*resp_authentication, 1),
3619 CreateMockRead(*body_authentication, 2),
3620 CreateMockRead(*resp_data, 4),
3621 CreateMockRead(*body_data, 5),
3622 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:133623 };
3624
rch8e6c6c42015-05-01 14:05:133625 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3626 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073627 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133628
[email protected]8ddf8322012-02-23 18:08:063629 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023630 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073631 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133632
[email protected]49639fa2011-12-20 23:22:413633 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133634
[email protected]262eec82013-03-19 21:01:363635 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503636 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133637
[email protected]49639fa2011-12-20 23:22:413638 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133639 EXPECT_EQ(ERR_IO_PENDING, rv);
3640
3641 rv = callback1.WaitForResult();
3642 EXPECT_EQ(OK, rv);
3643
3644 const HttpResponseInfo* const response = trans->GetResponseInfo();
3645
3646 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503647 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133648 EXPECT_EQ(407, response->headers->response_code());
3649 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043650 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133651
[email protected]49639fa2011-12-20 23:22:413652 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133653
[email protected]49639fa2011-12-20 23:22:413654 rv = trans->RestartWithAuth(
3655 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133656 EXPECT_EQ(ERR_IO_PENDING, rv);
3657
3658 rv = callback2.WaitForResult();
3659 EXPECT_EQ(OK, rv);
3660
3661 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3662
3663 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503664 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133665 EXPECT_EQ(200, response_restart->headers->response_code());
3666 // The password prompt info should not be set.
3667 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3668}
3669
[email protected]d9da5fe2010-10-13 22:37:163670// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023671TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273672 HttpRequestInfo request;
3673 request.method = "GET";
bncce36dca22015-04-21 22:11:233674 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273675 request.load_flags = 0;
3676
[email protected]d9da5fe2010-10-13 22:37:163677 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073678 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113679 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513680 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073681 session_deps_.net_log = log.bound().net_log();
3682 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163683
[email protected]262eec82013-03-19 21:01:363684 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503685 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163686
bncce36dca22015-04-21 22:11:233687 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343688 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233689 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3690 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:163691
bncce36dca22015-04-21 22:11:233692 const char get[] =
3693 "GET / HTTP/1.1\r\n"
3694 "Host: www.example.org\r\n"
3695 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193696 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023697 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3698 scoped_ptr<SpdyFrame> conn_resp(
3699 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163700 const char resp[] = "HTTP/1.1 200 OK\r\n"
3701 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193702 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023703 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193704 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023705 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193706 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203707 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043708
3709 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133710 CreateMockWrite(*connect, 0),
3711 CreateMockWrite(*wrapped_get, 2),
3712 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:043713 };
3714
[email protected]d9da5fe2010-10-13 22:37:163715 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133716 CreateMockRead(*conn_resp, 1, ASYNC),
3717 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
3718 CreateMockRead(*wrapped_body, 4, ASYNC),
3719 CreateMockRead(*wrapped_body, 5, ASYNC),
3720 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:163721 };
3722
rch8e6c6c42015-05-01 14:05:133723 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3724 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073725 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163726
[email protected]8ddf8322012-02-23 18:08:063727 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023728 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073729 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063730 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073731 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163732
[email protected]49639fa2011-12-20 23:22:413733 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163734
[email protected]49639fa2011-12-20 23:22:413735 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163736 EXPECT_EQ(ERR_IO_PENDING, rv);
3737
3738 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:133739 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:163740
[email protected]58e32bb2013-01-21 18:23:253741 LoadTimingInfo load_timing_info;
3742 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3743 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3744
[email protected]d9da5fe2010-10-13 22:37:163745 const HttpResponseInfo* response = trans->GetResponseInfo();
3746 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503747 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163748 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3749
3750 std::string response_data;
3751 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3752 EXPECT_EQ("1234567890", response_data);
3753}
3754
3755// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023756TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273757 HttpRequestInfo request;
3758 request.method = "GET";
bncce36dca22015-04-21 22:11:233759 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273760 request.load_flags = 0;
3761
[email protected]d9da5fe2010-10-13 22:37:163762 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073763 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113764 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513765 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073766 session_deps_.net_log = log.bound().net_log();
3767 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163768
[email protected]262eec82013-03-19 21:01:363769 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163771
bncce36dca22015-04-21 22:11:233772 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343773 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233774 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3775 // fetch https://www.example.org/ via SPDY
3776 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:463777 scoped_ptr<SpdyFrame> get(
3778 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023779 scoped_ptr<SpdyFrame> wrapped_get(
3780 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3781 scoped_ptr<SpdyFrame> conn_resp(
3782 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3783 scoped_ptr<SpdyFrame> get_resp(
3784 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193785 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023786 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3787 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3788 scoped_ptr<SpdyFrame> wrapped_body(
3789 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193790 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203791 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193792 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203793 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043794
3795 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:093796 CreateMockWrite(*connect, 0),
3797 CreateMockWrite(*wrapped_get, 2),
3798 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:043799 CreateMockWrite(*window_update_body, 7),
3800 };
3801
[email protected]d9da5fe2010-10-13 22:37:163802 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:093803 CreateMockRead(*conn_resp, 1, ASYNC),
3804 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:133805 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:093806 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:133807 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163808 };
3809
rch32320842015-05-16 15:57:093810 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3811 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073812 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163813
[email protected]8ddf8322012-02-23 18:08:063814 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023815 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073816 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063817 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023818 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073819 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163820
[email protected]49639fa2011-12-20 23:22:413821 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163822
[email protected]49639fa2011-12-20 23:22:413823 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163824 EXPECT_EQ(ERR_IO_PENDING, rv);
3825
rch32320842015-05-16 15:57:093826 // Allow the SpdyProxyClientSocket's write callback to complete.
3827 base::MessageLoop::current()->RunUntilIdle();
3828 // Now allow the read of the response to complete.
3829 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:163830 rv = callback1.WaitForResult();
3831 EXPECT_EQ(OK, rv);
3832
[email protected]58e32bb2013-01-21 18:23:253833 LoadTimingInfo load_timing_info;
3834 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3835 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3836
[email protected]d9da5fe2010-10-13 22:37:163837 const HttpResponseInfo* response = trans->GetResponseInfo();
3838 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503839 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163840 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3841
3842 std::string response_data;
3843 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233844 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163845}
3846
3847// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023848TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273849 HttpRequestInfo request;
3850 request.method = "GET";
bncce36dca22015-04-21 22:11:233851 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273852 request.load_flags = 0;
3853
[email protected]d9da5fe2010-10-13 22:37:163854 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073855 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113856 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513857 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073858 session_deps_.net_log = log.bound().net_log();
3859 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163860
[email protected]262eec82013-03-19 21:01:363861 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503862 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163863
bncce36dca22015-04-21 22:11:233864 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343865 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233866 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:203867 scoped_ptr<SpdyFrame> get(
3868 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163869
3870 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133871 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:163872 };
3873
[email protected]23e482282013-06-14 16:08:023874 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3875 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163876 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133877 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:163878 };
3879
rch8e6c6c42015-05-01 14:05:133880 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3881 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073882 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163883
[email protected]8ddf8322012-02-23 18:08:063884 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023885 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073886 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063887 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023888 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073889 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163890
[email protected]49639fa2011-12-20 23:22:413891 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163892
[email protected]49639fa2011-12-20 23:22:413893 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163894 EXPECT_EQ(ERR_IO_PENDING, rv);
3895
3896 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173897 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163898
[email protected]4eddbc732012-08-09 05:40:173899 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163900}
3901
[email protected]f6c63db52013-02-02 00:35:223902// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3903// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023904TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223905 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3906 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073907 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223908 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513909 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073910 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223911 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:503912 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223913
3914 HttpRequestInfo request1;
3915 request1.method = "GET";
bncce36dca22015-04-21 22:11:233916 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223917 request1.load_flags = 0;
3918
3919 HttpRequestInfo request2;
3920 request2.method = "GET";
bncce36dca22015-04-21 22:11:233921 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:223922 request2.load_flags = 0;
3923
bncce36dca22015-04-21 22:11:233924 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343925 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233926 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023927 scoped_ptr<SpdyFrame> conn_resp1(
3928 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223929
bncce36dca22015-04-21 22:11:233930 // Fetch https://www.example.org/ via HTTP.
3931 const char get1[] =
3932 "GET / HTTP/1.1\r\n"
3933 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223934 "Connection: keep-alive\r\n\r\n";
3935 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023936 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223937 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3938 "Content-Length: 1\r\n\r\n";
3939 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023940 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3941 scoped_ptr<SpdyFrame> wrapped_body1(
3942 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223943 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203944 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223945
bncce36dca22015-04-21 22:11:233946 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293947 SpdyHeaderBlock connect2_block;
3948 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnc6b996d532015-07-29 10:51:323949 if (GetParam() >= kProtoHTTP2MinimumVersion) {
3950 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
3951 } else {
3952 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
3953 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
3954 }
[email protected]745aa9c2014-06-27 02:21:293955 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223956 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293957 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393958
[email protected]23e482282013-06-14 16:08:023959 scoped_ptr<SpdyFrame> conn_resp2(
3960 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223961
bncce36dca22015-04-21 22:11:233962 // Fetch https://mail.example.org/ via HTTP.
3963 const char get2[] =
3964 "GET / HTTP/1.1\r\n"
3965 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223966 "Connection: keep-alive\r\n\r\n";
3967 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023968 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223969 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3970 "Content-Length: 2\r\n\r\n";
3971 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023972 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223973 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023974 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223975
3976 MockWrite spdy_writes[] = {
3977 CreateMockWrite(*connect1, 0),
3978 CreateMockWrite(*wrapped_get1, 2),
3979 CreateMockWrite(*connect2, 5),
3980 CreateMockWrite(*wrapped_get2, 7),
3981 };
3982
3983 MockRead spdy_reads[] = {
3984 CreateMockRead(*conn_resp1, 1, ASYNC),
3985 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3986 CreateMockRead(*wrapped_body1, 4, ASYNC),
3987 CreateMockRead(*conn_resp2, 6, ASYNC),
3988 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3989 CreateMockRead(*wrapped_body2, 9, ASYNC),
3990 MockRead(ASYNC, 0, 10),
3991 };
3992
mmenke11eb5152015-06-09 14:50:503993 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3994 arraysize(spdy_writes));
3995 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223996
3997 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023998 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:503999 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224000 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504001 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224002 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504003 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:224004
4005 TestCompletionCallback callback;
4006
[email protected]262eec82013-03-19 21:01:364007 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504008 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224009 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504010 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224011
4012 LoadTimingInfo load_timing_info;
4013 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4014 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4015
4016 const HttpResponseInfo* response = trans->GetResponseInfo();
4017 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504018 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224019 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4020
4021 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294022 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504023 rv = trans->Read(buf.get(), 256, callback.callback());
4024 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224025
[email protected]262eec82013-03-19 21:01:364026 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504027 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224028 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504029 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224030
4031 LoadTimingInfo load_timing_info2;
4032 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4033 // Even though the SPDY connection is reused, a new tunnelled connection has
4034 // to be created, so the socket's load timing looks like a fresh connection.
4035 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
4036
4037 // The requests should have different IDs, since they each are using their own
4038 // separate stream.
4039 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4040
mmenke11eb5152015-06-09 14:50:504041 rv = trans2->Read(buf.get(), 256, callback.callback());
4042 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224043}
4044
4045// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4046// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:024047TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224048 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
4049 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074050 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224051 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514052 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074053 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224054 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504055 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224056
4057 HttpRequestInfo request1;
4058 request1.method = "GET";
bncce36dca22015-04-21 22:11:234059 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224060 request1.load_flags = 0;
4061
4062 HttpRequestInfo request2;
4063 request2.method = "GET";
bncce36dca22015-04-21 22:11:234064 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:224065 request2.load_flags = 0;
4066
bncce36dca22015-04-21 22:11:234067 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344068 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234069 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024070 scoped_ptr<SpdyFrame> conn_resp1(
4071 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224072
bncce36dca22015-04-21 22:11:234073 // Fetch https://www.example.org/ via HTTP.
4074 const char get1[] =
4075 "GET / HTTP/1.1\r\n"
4076 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224077 "Connection: keep-alive\r\n\r\n";
4078 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024079 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224080 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4081 "Content-Length: 1\r\n\r\n";
4082 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024083 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4084 scoped_ptr<SpdyFrame> wrapped_body1(
4085 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224086 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204087 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224088
bncce36dca22015-04-21 22:11:234089 // Fetch https://www.example.org/2 via HTTP.
4090 const char get2[] =
4091 "GET /2 HTTP/1.1\r\n"
4092 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224093 "Connection: keep-alive\r\n\r\n";
4094 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024095 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224096 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4097 "Content-Length: 2\r\n\r\n";
4098 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024099 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224100 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024101 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224102
4103 MockWrite spdy_writes[] = {
4104 CreateMockWrite(*connect1, 0),
4105 CreateMockWrite(*wrapped_get1, 2),
4106 CreateMockWrite(*wrapped_get2, 5),
4107 };
4108
4109 MockRead spdy_reads[] = {
4110 CreateMockRead(*conn_resp1, 1, ASYNC),
4111 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4112 CreateMockRead(*wrapped_body1, 4, ASYNC),
4113 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4114 CreateMockRead(*wrapped_body2, 7, ASYNC),
4115 MockRead(ASYNC, 0, 8),
4116 };
4117
mmenke11eb5152015-06-09 14:50:504118 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4119 arraysize(spdy_writes));
4120 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224121
4122 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024123 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504124 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224125 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504126 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224127
4128 TestCompletionCallback callback;
4129
[email protected]262eec82013-03-19 21:01:364130 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504131 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224132 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4133 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224134
4135 rv = callback.WaitForResult();
4136 EXPECT_EQ(OK, rv);
4137
4138 LoadTimingInfo load_timing_info;
4139 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4140 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4141
4142 const HttpResponseInfo* response = trans->GetResponseInfo();
4143 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504144 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224145 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4146
4147 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294148 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504149 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224150 trans.reset();
4151
[email protected]262eec82013-03-19 21:01:364152 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504153 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224154 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4155 EXPECT_EQ(ERR_IO_PENDING, rv);
4156
[email protected]f6c63db52013-02-02 00:35:224157 rv = callback.WaitForResult();
4158 EXPECT_EQ(OK, rv);
4159
4160 LoadTimingInfo load_timing_info2;
4161 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4162 TestLoadTimingReused(load_timing_info2);
4163
4164 // The requests should have the same ID.
4165 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4166
[email protected]90499482013-06-01 00:39:504167 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224168}
4169
4170// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4171// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504172TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224173 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074174 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224175 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514176 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074177 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224178 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504179 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224180
4181 HttpRequestInfo request1;
4182 request1.method = "GET";
bncce36dca22015-04-21 22:11:234183 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224184 request1.load_flags = 0;
4185
4186 HttpRequestInfo request2;
4187 request2.method = "GET";
bncce36dca22015-04-21 22:11:234188 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224189 request2.load_flags = 0;
4190
bncce36dca22015-04-21 22:11:234191 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024192 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234193 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294194 scoped_ptr<SpdyFrame> get1(
4195 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024196 scoped_ptr<SpdyFrame> get_resp1(
4197 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4198 scoped_ptr<SpdyFrame> body1(
4199 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224200
bncce36dca22015-04-21 22:11:234201 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024202 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234203 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294204 scoped_ptr<SpdyFrame> get2(
4205 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024206 scoped_ptr<SpdyFrame> get_resp2(
4207 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4208 scoped_ptr<SpdyFrame> body2(
4209 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224210
4211 MockWrite spdy_writes[] = {
4212 CreateMockWrite(*get1, 0),
4213 CreateMockWrite(*get2, 3),
4214 };
4215
4216 MockRead spdy_reads[] = {
4217 CreateMockRead(*get_resp1, 1, ASYNC),
4218 CreateMockRead(*body1, 2, ASYNC),
4219 CreateMockRead(*get_resp2, 4, ASYNC),
4220 CreateMockRead(*body2, 5, ASYNC),
4221 MockRead(ASYNC, 0, 6),
4222 };
4223
mmenke11eb5152015-06-09 14:50:504224 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4225 arraysize(spdy_writes));
4226 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224227
4228 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024229 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504230 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224231
4232 TestCompletionCallback callback;
4233
[email protected]262eec82013-03-19 21:01:364234 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504235 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224236 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504237 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224238
4239 LoadTimingInfo load_timing_info;
4240 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4241 TestLoadTimingNotReused(load_timing_info,
4242 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4243
4244 const HttpResponseInfo* response = trans->GetResponseInfo();
4245 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504246 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224247 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4248
4249 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294250 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504251 rv = trans->Read(buf.get(), 256, callback.callback());
4252 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224253 // Delete the first request, so the second one can reuse the socket.
4254 trans.reset();
4255
[email protected]262eec82013-03-19 21:01:364256 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504257 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224258 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504259 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224260
4261 LoadTimingInfo load_timing_info2;
4262 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4263 TestLoadTimingReused(load_timing_info2);
4264
4265 // The requests should have the same ID.
4266 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4267
mmenke11eb5152015-06-09 14:50:504268 rv = trans2->Read(buf.get(), 256, callback.callback());
4269 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224270}
4271
[email protected]2df19bb2010-08-25 20:13:464272// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024273TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464274 HttpRequestInfo request;
4275 request.method = "GET";
bncce36dca22015-04-21 22:11:234276 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464277 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294278 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464279
[email protected]79cb5c12011-09-12 13:12:044280 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074281 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:044282 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:514283 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074284 session_deps_.net_log = log.bound().net_log();
4285 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274286
[email protected]2df19bb2010-08-25 20:13:464287 // Since we have proxy, should use full url
4288 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234289 MockWrite(
4290 "GET http://www.example.org/ HTTP/1.1\r\n"
4291 "Host: www.example.org\r\n"
4292 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464293
bncce36dca22015-04-21 22:11:234294 // After calling trans->RestartWithAuth(), this is the request we should
4295 // be issuing -- the final header line contains the credentials.
4296 MockWrite(
4297 "GET http://www.example.org/ HTTP/1.1\r\n"
4298 "Host: www.example.org\r\n"
4299 "Proxy-Connection: keep-alive\r\n"
4300 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464301 };
4302
4303 // The proxy responds to the GET with a 407, using a persistent
4304 // connection.
4305 MockRead data_reads1[] = {
4306 // No credentials.
4307 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4308 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4309 MockRead("Proxy-Connection: keep-alive\r\n"),
4310 MockRead("Content-Length: 0\r\n\r\n"),
4311
4312 MockRead("HTTP/1.1 200 OK\r\n"),
4313 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4314 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064315 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464316 };
4317
4318 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4319 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074320 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064321 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074322 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464323
[email protected]49639fa2011-12-20 23:22:414324 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464325
[email protected]262eec82013-03-19 21:01:364326 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504327 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504328
[email protected]49639fa2011-12-20 23:22:414329 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464330 EXPECT_EQ(ERR_IO_PENDING, rv);
4331
4332 rv = callback1.WaitForResult();
4333 EXPECT_EQ(OK, rv);
4334
[email protected]58e32bb2013-01-21 18:23:254335 LoadTimingInfo load_timing_info;
4336 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4337 TestLoadTimingNotReused(load_timing_info,
4338 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4339
[email protected]2df19bb2010-08-25 20:13:464340 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504341 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504342 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464343 EXPECT_EQ(407, response->headers->response_code());
4344 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044345 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464346
[email protected]49639fa2011-12-20 23:22:414347 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464348
[email protected]49639fa2011-12-20 23:22:414349 rv = trans->RestartWithAuth(
4350 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464351 EXPECT_EQ(ERR_IO_PENDING, rv);
4352
4353 rv = callback2.WaitForResult();
4354 EXPECT_EQ(OK, rv);
4355
[email protected]58e32bb2013-01-21 18:23:254356 load_timing_info = LoadTimingInfo();
4357 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4358 // Retrying with HTTP AUTH is considered to be reusing a socket.
4359 TestLoadTimingReused(load_timing_info);
4360
[email protected]2df19bb2010-08-25 20:13:464361 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504362 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464363
4364 EXPECT_TRUE(response->headers->IsKeepAlive());
4365 EXPECT_EQ(200, response->headers->response_code());
4366 EXPECT_EQ(100, response->headers->GetContentLength());
4367 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4368
4369 // The password prompt info should not be set.
4370 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4371}
4372
[email protected]23e482282013-06-14 16:08:024373void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084374 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424375 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084376 request.method = "GET";
bncce36dca22015-04-21 22:11:234377 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084378 request.load_flags = 0;
4379
[email protected]cb9bf6ca2011-01-28 13:15:274380 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074381 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:074382 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274383
[email protected]c744cf22009-02-27 07:28:084384 // Since we have proxy, should try to establish tunnel.
4385 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234386 MockWrite(
4387 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4388 "Host: www.example.org\r\n"
4389 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084390 };
4391
4392 MockRead data_reads[] = {
4393 status,
4394 MockRead("Content-Length: 10\r\n\r\n"),
4395 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064396 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084397 };
4398
[email protected]31a2bfe2010-02-09 08:03:394399 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4400 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074401 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084402
[email protected]49639fa2011-12-20 23:22:414403 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084404
[email protected]262eec82013-03-19 21:01:364405 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504406 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504407
[email protected]49639fa2011-12-20 23:22:414408 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424409 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084410
4411 rv = callback.WaitForResult();
4412 EXPECT_EQ(expected_status, rv);
4413}
4414
[email protected]23e482282013-06-14 16:08:024415void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234416 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084417 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424418 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084419}
4420
[email protected]23e482282013-06-14 16:08:024421TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084422 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4423}
4424
[email protected]23e482282013-06-14 16:08:024425TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084426 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4427}
4428
[email protected]23e482282013-06-14 16:08:024429TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084430 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4431}
4432
[email protected]23e482282013-06-14 16:08:024433TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084434 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4435}
4436
[email protected]23e482282013-06-14 16:08:024437TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084438 ConnectStatusHelper(
4439 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4440}
4441
[email protected]23e482282013-06-14 16:08:024442TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084443 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4444}
4445
[email protected]23e482282013-06-14 16:08:024446TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084447 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4448}
4449
[email protected]23e482282013-06-14 16:08:024450TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084451 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4452}
4453
[email protected]23e482282013-06-14 16:08:024454TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084455 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4456}
4457
[email protected]23e482282013-06-14 16:08:024458TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084459 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4460}
4461
[email protected]23e482282013-06-14 16:08:024462TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084463 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4464}
4465
[email protected]23e482282013-06-14 16:08:024466TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084467 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4468}
4469
[email protected]23e482282013-06-14 16:08:024470TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084471 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4472}
4473
[email protected]23e482282013-06-14 16:08:024474TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084475 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4476}
4477
[email protected]23e482282013-06-14 16:08:024478TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084479 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4480}
4481
[email protected]23e482282013-06-14 16:08:024482TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084483 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4484}
4485
[email protected]0a17aab32014-04-24 03:32:374486TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4487 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4488}
4489
[email protected]23e482282013-06-14 16:08:024490TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084491 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4492}
4493
[email protected]23e482282013-06-14 16:08:024494TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084495 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4496}
4497
[email protected]23e482282013-06-14 16:08:024498TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084499 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4500}
4501
[email protected]23e482282013-06-14 16:08:024502TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084503 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4504}
4505
[email protected]23e482282013-06-14 16:08:024506TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084507 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4508}
4509
[email protected]23e482282013-06-14 16:08:024510TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084511 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4512}
4513
[email protected]23e482282013-06-14 16:08:024514TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084515 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4516}
4517
[email protected]23e482282013-06-14 16:08:024518TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084519 ConnectStatusHelperWithExpectedStatus(
4520 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544521 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084522}
4523
[email protected]23e482282013-06-14 16:08:024524TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084525 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4526}
4527
[email protected]23e482282013-06-14 16:08:024528TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084529 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4530}
4531
[email protected]23e482282013-06-14 16:08:024532TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084533 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4534}
4535
[email protected]23e482282013-06-14 16:08:024536TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084537 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4538}
4539
[email protected]23e482282013-06-14 16:08:024540TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084541 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4542}
4543
[email protected]23e482282013-06-14 16:08:024544TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084545 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4546}
4547
[email protected]23e482282013-06-14 16:08:024548TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084549 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4550}
4551
[email protected]23e482282013-06-14 16:08:024552TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084553 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4554}
4555
[email protected]23e482282013-06-14 16:08:024556TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084557 ConnectStatusHelper(
4558 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4559}
4560
[email protected]23e482282013-06-14 16:08:024561TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084562 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4563}
4564
[email protected]23e482282013-06-14 16:08:024565TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084566 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4567}
4568
[email protected]23e482282013-06-14 16:08:024569TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084570 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4571}
4572
[email protected]23e482282013-06-14 16:08:024573TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084574 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4575}
4576
[email protected]23e482282013-06-14 16:08:024577TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084578 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4579}
4580
[email protected]23e482282013-06-14 16:08:024581TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084582 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4583}
4584
[email protected]23e482282013-06-14 16:08:024585TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084586 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4587}
4588
[email protected]038e9a32008-10-08 22:40:164589// Test the flow when both the proxy server AND origin server require
4590// authentication. Again, this uses basic auth for both since that is
4591// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024592TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274593 HttpRequestInfo request;
4594 request.method = "GET";
bncce36dca22015-04-21 22:11:234595 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274596 request.load_flags = 0;
4597
[email protected]038e9a32008-10-08 22:40:164598 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074599 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4600 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4601
4602 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414603 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164604
[email protected]f9ee6b52008-11-08 06:46:234605 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234606 MockWrite(
4607 "GET http://www.example.org/ HTTP/1.1\r\n"
4608 "Host: www.example.org\r\n"
4609 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:234610 };
4611
[email protected]038e9a32008-10-08 22:40:164612 MockRead data_reads1[] = {
4613 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4614 // Give a couple authenticate options (only the middle one is actually
4615 // supported).
[email protected]22927ad2009-09-21 19:56:194616 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164617 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4618 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4619 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4620 // Large content-length -- won't matter, as connection will be reset.
4621 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064622 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164623 };
4624
4625 // After calling trans->RestartWithAuth() the first time, this is the
4626 // request we should be issuing -- the final header line contains the
4627 // proxy's credentials.
4628 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:234629 MockWrite(
4630 "GET http://www.example.org/ HTTP/1.1\r\n"
4631 "Host: www.example.org\r\n"
4632 "Proxy-Connection: keep-alive\r\n"
4633 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164634 };
4635
4636 // Now the proxy server lets the request pass through to origin server.
4637 // The origin server responds with a 401.
4638 MockRead data_reads2[] = {
4639 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4640 // Note: We are using the same realm-name as the proxy server. This is
4641 // completely valid, as realms are unique across hosts.
4642 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4643 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4644 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064645 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164646 };
4647
4648 // After calling trans->RestartWithAuth() the second time, we should send
4649 // the credentials for both the proxy and origin server.
4650 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:234651 MockWrite(
4652 "GET http://www.example.org/ HTTP/1.1\r\n"
4653 "Host: www.example.org\r\n"
4654 "Proxy-Connection: keep-alive\r\n"
4655 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4656 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164657 };
4658
4659 // Lastly we get the desired content.
4660 MockRead data_reads3[] = {
4661 MockRead("HTTP/1.0 200 OK\r\n"),
4662 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4663 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064664 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164665 };
4666
[email protected]31a2bfe2010-02-09 08:03:394667 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4668 data_writes1, arraysize(data_writes1));
4669 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4670 data_writes2, arraysize(data_writes2));
4671 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4672 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074673 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4674 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4675 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164676
[email protected]49639fa2011-12-20 23:22:414677 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164678
[email protected]49639fa2011-12-20 23:22:414679 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424680 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164681
4682 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424683 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164684
[email protected]1c773ea12009-04-28 19:58:424685 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504686 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044687 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164688
[email protected]49639fa2011-12-20 23:22:414689 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164690
[email protected]49639fa2011-12-20 23:22:414691 rv = trans->RestartWithAuth(
4692 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424693 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164694
4695 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424696 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164697
4698 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504699 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044700 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164701
[email protected]49639fa2011-12-20 23:22:414702 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164703
[email protected]49639fa2011-12-20 23:22:414704 rv = trans->RestartWithAuth(
4705 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424706 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164707
4708 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424709 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164710
4711 response = trans->GetResponseInfo();
4712 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4713 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164714}
[email protected]4ddaf2502008-10-23 18:26:194715
[email protected]ea9dc9a2009-09-05 00:43:324716// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4717// can't hook into its internals to cause it to generate predictable NTLM
4718// authorization headers.
4719#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294720// The NTLM authentication unit tests were generated by capturing the HTTP
4721// requests and responses using Fiddler 2 and inspecting the generated random
4722// bytes in the debugger.
4723
4724// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024725TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424726 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244727 request.method = "GET";
4728 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544729
4730 // Ensure load is not disrupted by flags which suppress behaviour specific
4731 // to other auth schemes.
4732 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244733
[email protected]cb9bf6ca2011-01-28 13:15:274734 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4735 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074736 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274737
[email protected]3f918782009-02-28 01:29:244738 MockWrite data_writes1[] = {
4739 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4740 "Host: 172.22.68.17\r\n"
4741 "Connection: keep-alive\r\n\r\n"),
4742 };
4743
4744 MockRead data_reads1[] = {
4745 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044746 // Negotiate and NTLM are often requested together. However, we only want
4747 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4748 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244749 MockRead("WWW-Authenticate: NTLM\r\n"),
4750 MockRead("Connection: close\r\n"),
4751 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364752 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244753 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064754 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244755 };
4756
4757 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224758 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244759 // request we should be issuing -- the final header line contains a Type
4760 // 1 message.
4761 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4762 "Host: 172.22.68.17\r\n"
4763 "Connection: keep-alive\r\n"
4764 "Authorization: NTLM "
4765 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4766
4767 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4768 // (the credentials for the origin server). The second request continues
4769 // on the same connection.
4770 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4771 "Host: 172.22.68.17\r\n"
4772 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294773 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4774 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4775 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4776 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4777 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244778 };
4779
4780 MockRead data_reads2[] = {
4781 // The origin server responds with a Type 2 message.
4782 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4783 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294784 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244785 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4786 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4787 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4788 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4789 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4790 "BtAAAAAAA=\r\n"),
4791 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364792 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244793 MockRead("You are not authorized to view this page\r\n"),
4794
4795 // Lastly we get the desired content.
4796 MockRead("HTTP/1.1 200 OK\r\n"),
4797 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4798 MockRead("Content-Length: 13\r\n\r\n"),
4799 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064800 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244801 };
4802
[email protected]31a2bfe2010-02-09 08:03:394803 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4804 data_writes1, arraysize(data_writes1));
4805 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4806 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074807 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4808 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244809
[email protected]49639fa2011-12-20 23:22:414810 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244811
[email protected]262eec82013-03-19 21:01:364812 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504813 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504814
[email protected]49639fa2011-12-20 23:22:414815 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424816 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244817
4818 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424819 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244820
[email protected]0757e7702009-03-27 04:00:224821 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4822
[email protected]1c773ea12009-04-28 19:58:424823 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044824 ASSERT_FALSE(response == NULL);
4825 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244826
[email protected]49639fa2011-12-20 23:22:414827 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254828
[email protected]f3cf9802011-10-28 18:44:584829 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414830 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254831 EXPECT_EQ(ERR_IO_PENDING, rv);
4832
4833 rv = callback2.WaitForResult();
4834 EXPECT_EQ(OK, rv);
4835
4836 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4837
4838 response = trans->GetResponseInfo();
4839 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254840 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4841
[email protected]49639fa2011-12-20 23:22:414842 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244843
[email protected]49639fa2011-12-20 23:22:414844 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424845 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244846
[email protected]0757e7702009-03-27 04:00:224847 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424848 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244849
4850 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504851 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244852 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4853 EXPECT_EQ(13, response->headers->GetContentLength());
4854}
4855
[email protected]385a4672009-03-11 22:21:294856// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024857TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424858 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294859 request.method = "GET";
4860 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4861 request.load_flags = 0;
4862
[email protected]cb9bf6ca2011-01-28 13:15:274863 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4864 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074865 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274866
[email protected]385a4672009-03-11 22:21:294867 MockWrite data_writes1[] = {
4868 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4869 "Host: 172.22.68.17\r\n"
4870 "Connection: keep-alive\r\n\r\n"),
4871 };
4872
4873 MockRead data_reads1[] = {
4874 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044875 // Negotiate and NTLM are often requested together. However, we only want
4876 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4877 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294878 MockRead("WWW-Authenticate: NTLM\r\n"),
4879 MockRead("Connection: close\r\n"),
4880 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364881 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294882 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064883 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294884 };
4885
4886 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224887 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294888 // request we should be issuing -- the final header line contains a Type
4889 // 1 message.
4890 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4891 "Host: 172.22.68.17\r\n"
4892 "Connection: keep-alive\r\n"
4893 "Authorization: NTLM "
4894 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4895
4896 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4897 // (the credentials for the origin server). The second request continues
4898 // on the same connection.
4899 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4900 "Host: 172.22.68.17\r\n"
4901 "Connection: keep-alive\r\n"
4902 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4903 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4904 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4905 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4906 "4Ww7b7E=\r\n\r\n"),
4907 };
4908
4909 MockRead data_reads2[] = {
4910 // The origin server responds with a Type 2 message.
4911 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4912 MockRead("WWW-Authenticate: NTLM "
4913 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4914 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4915 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4916 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4917 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4918 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4919 "BtAAAAAAA=\r\n"),
4920 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364921 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294922 MockRead("You are not authorized to view this page\r\n"),
4923
4924 // Wrong password.
4925 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294926 MockRead("WWW-Authenticate: NTLM\r\n"),
4927 MockRead("Connection: close\r\n"),
4928 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364929 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294930 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064931 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294932 };
4933
4934 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224935 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294936 // request we should be issuing -- the final header line contains a Type
4937 // 1 message.
4938 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4939 "Host: 172.22.68.17\r\n"
4940 "Connection: keep-alive\r\n"
4941 "Authorization: NTLM "
4942 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4943
4944 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4945 // (the credentials for the origin server). The second request continues
4946 // on the same connection.
4947 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4948 "Host: 172.22.68.17\r\n"
4949 "Connection: keep-alive\r\n"
4950 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4951 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4952 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4953 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4954 "+4MUm7c=\r\n\r\n"),
4955 };
4956
4957 MockRead data_reads3[] = {
4958 // The origin server responds with a Type 2 message.
4959 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4960 MockRead("WWW-Authenticate: NTLM "
4961 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4962 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4963 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4964 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4965 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4966 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4967 "BtAAAAAAA=\r\n"),
4968 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364969 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294970 MockRead("You are not authorized to view this page\r\n"),
4971
4972 // Lastly we get the desired content.
4973 MockRead("HTTP/1.1 200 OK\r\n"),
4974 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4975 MockRead("Content-Length: 13\r\n\r\n"),
4976 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064977 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294978 };
4979
[email protected]31a2bfe2010-02-09 08:03:394980 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4981 data_writes1, arraysize(data_writes1));
4982 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4983 data_writes2, arraysize(data_writes2));
4984 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4985 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074986 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4987 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4988 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294989
[email protected]49639fa2011-12-20 23:22:414990 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294991
[email protected]262eec82013-03-19 21:01:364992 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504993 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504994
[email protected]49639fa2011-12-20 23:22:414995 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424996 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294997
4998 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424999 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295000
[email protected]0757e7702009-03-27 04:00:225001 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:295002
[email protected]1c773ea12009-04-28 19:58:425003 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505004 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045005 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:295006
[email protected]49639fa2011-12-20 23:22:415007 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:295008
[email protected]0757e7702009-03-27 04:00:225009 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:585010 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:415011 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425012 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295013
[email protected]10af5fe72011-01-31 16:17:255014 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425015 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295016
[email protected]0757e7702009-03-27 04:00:225017 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415018 TestCompletionCallback callback3;
5019 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425020 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:255021 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425022 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225023 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5024
5025 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045026 ASSERT_FALSE(response == NULL);
5027 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:225028
[email protected]49639fa2011-12-20 23:22:415029 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:225030
5031 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:585032 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415033 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:255034 EXPECT_EQ(ERR_IO_PENDING, rv);
5035
5036 rv = callback4.WaitForResult();
5037 EXPECT_EQ(OK, rv);
5038
5039 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5040
[email protected]49639fa2011-12-20 23:22:415041 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:255042
5043 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:415044 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:425045 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225046
5047 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425048 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225049
[email protected]385a4672009-03-11 22:21:295050 response = trans->GetResponseInfo();
5051 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5052 EXPECT_EQ(13, response->headers->GetContentLength());
5053}
[email protected]ea9dc9a2009-09-05 00:43:325054#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:295055
[email protected]4ddaf2502008-10-23 18:26:195056// Test reading a server response which has only headers, and no body.
5057// After some maximum number of bytes is consumed, the transaction should
5058// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:025059TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:425060 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:195061 request.method = "GET";
bncce36dca22015-04-21 22:11:235062 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:195063 request.load_flags = 0;
5064
[email protected]3fe8d2f82013-10-17 08:56:075065 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275066 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415067 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275068
[email protected]b75b7b2f2009-10-06 00:54:535069 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:435070 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:535071 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:195072
5073 MockRead data_reads[] = {
5074 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065075 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:195076 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:065077 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:195078 };
[email protected]31a2bfe2010-02-09 08:03:395079 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075080 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:195081
[email protected]49639fa2011-12-20 23:22:415082 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195083
[email protected]49639fa2011-12-20 23:22:415084 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425085 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195086
5087 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425088 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195089}
[email protected]f4e426b2008-11-05 00:24:495090
5091// Make sure that we don't try to reuse a TCPClientSocket when failing to
5092// establish tunnel.
5093// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025094TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235095 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275096 HttpRequestInfo request;
5097 request.method = "GET";
bncce36dca22015-04-21 22:11:235098 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275099 request.load_flags = 0;
5100
[email protected]f4e426b2008-11-05 00:24:495101 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075102 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:015103
[email protected]bb88e1d32013-05-03 23:11:075104 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495105
[email protected]262eec82013-03-19 21:01:365106 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505107 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495108
[email protected]f4e426b2008-11-05 00:24:495109 // Since we have proxy, should try to establish tunnel.
5110 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235111 MockWrite(
5112 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5113 "Host: www.example.org\r\n"
5114 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495115 };
5116
[email protected]77848d12008-11-14 00:00:225117 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495118 // connection. Usually a proxy would return 501 (not implemented),
5119 // or 200 (tunnel established).
5120 MockRead data_reads1[] = {
5121 MockRead("HTTP/1.1 404 Not Found\r\n"),
5122 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065123 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495124 };
5125
[email protected]31a2bfe2010-02-09 08:03:395126 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5127 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075128 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495129
[email protected]49639fa2011-12-20 23:22:415130 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495131
[email protected]49639fa2011-12-20 23:22:415132 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425133 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495134
5135 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425136 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495137
[email protected]b4404c02009-04-10 16:38:525138 // Empty the current queue. This is necessary because idle sockets are
5139 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345140 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525141
[email protected]f4e426b2008-11-05 00:24:495142 // We now check to make sure the TCPClientSocket was not added back to
5143 // the pool.
[email protected]90499482013-06-01 00:39:505144 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495145 trans.reset();
[email protected]2da659e2013-05-23 20:51:345146 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495147 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505148 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495149}
[email protected]372d34a2008-11-05 21:30:515150
[email protected]1b157c02009-04-21 01:55:405151// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025152TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425153 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405154 request.method = "GET";
bncce36dca22015-04-21 22:11:235155 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405156 request.load_flags = 0;
5157
[email protected]bb88e1d32013-05-03 23:11:075158 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275159
[email protected]262eec82013-03-19 21:01:365160 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505161 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275162
[email protected]1b157c02009-04-21 01:55:405163 MockRead data_reads[] = {
5164 // A part of the response body is received with the response headers.
5165 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5166 // The rest of the response body is received in two parts.
5167 MockRead("lo"),
5168 MockRead(" world"),
5169 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065170 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405171 };
5172
[email protected]31a2bfe2010-02-09 08:03:395173 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075174 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405175
[email protected]49639fa2011-12-20 23:22:415176 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405177
[email protected]49639fa2011-12-20 23:22:415178 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425179 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405180
5181 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425182 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405183
[email protected]1c773ea12009-04-28 19:58:425184 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505185 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405186
[email protected]90499482013-06-01 00:39:505187 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405188 std::string status_line = response->headers->GetStatusLine();
5189 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5190
[email protected]90499482013-06-01 00:39:505191 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405192
5193 std::string response_data;
5194 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425195 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405196 EXPECT_EQ("hello world", response_data);
5197
5198 // Empty the current queue. This is necessary because idle sockets are
5199 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345200 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405201
5202 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505203 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405204}
5205
[email protected]76a505b2010-08-25 06:23:005206// Make sure that we recycle a SSL socket after reading all of the response
5207// body.
[email protected]23e482282013-06-14 16:08:025208TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005209 HttpRequestInfo request;
5210 request.method = "GET";
bncce36dca22015-04-21 22:11:235211 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005212 request.load_flags = 0;
5213
5214 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235215 MockWrite(
5216 "GET / HTTP/1.1\r\n"
5217 "Host: www.example.org\r\n"
5218 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005219 };
5220
5221 MockRead data_reads[] = {
5222 MockRead("HTTP/1.1 200 OK\r\n"),
5223 MockRead("Content-Length: 11\r\n\r\n"),
5224 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065225 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005226 };
5227
[email protected]8ddf8322012-02-23 18:08:065228 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075229 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005230
5231 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5232 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075233 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005234
[email protected]49639fa2011-12-20 23:22:415235 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005236
[email protected]bb88e1d32013-05-03 23:11:075237 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365238 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505239 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005240
[email protected]49639fa2011-12-20 23:22:415241 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005242
5243 EXPECT_EQ(ERR_IO_PENDING, rv);
5244 EXPECT_EQ(OK, callback.WaitForResult());
5245
5246 const HttpResponseInfo* response = trans->GetResponseInfo();
5247 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505248 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005249 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5250
[email protected]90499482013-06-01 00:39:505251 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005252
5253 std::string response_data;
5254 rv = ReadTransaction(trans.get(), &response_data);
5255 EXPECT_EQ(OK, rv);
5256 EXPECT_EQ("hello world", response_data);
5257
5258 // Empty the current queue. This is necessary because idle sockets are
5259 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345260 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005261
5262 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505263 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005264}
5265
5266// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5267// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025268TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005269 HttpRequestInfo request;
5270 request.method = "GET";
bncce36dca22015-04-21 22:11:235271 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005272 request.load_flags = 0;
5273
5274 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235275 MockWrite(
5276 "GET / HTTP/1.1\r\n"
5277 "Host: www.example.org\r\n"
5278 "Connection: keep-alive\r\n\r\n"),
5279 MockWrite(
5280 "GET / HTTP/1.1\r\n"
5281 "Host: www.example.org\r\n"
5282 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005283 };
5284
5285 MockRead data_reads[] = {
5286 MockRead("HTTP/1.1 200 OK\r\n"),
5287 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065288 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005289 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065290 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005291 };
5292
[email protected]8ddf8322012-02-23 18:08:065293 SSLSocketDataProvider ssl(ASYNC, OK);
5294 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075295 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005297
5298 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5299 data_writes, arraysize(data_writes));
5300 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5301 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075302 session_deps_.socket_factory->AddSocketDataProvider(&data);
5303 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005304
[email protected]49639fa2011-12-20 23:22:415305 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005306
[email protected]bb88e1d32013-05-03 23:11:075307 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365308 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505309 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005310
[email protected]49639fa2011-12-20 23:22:415311 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005312
5313 EXPECT_EQ(ERR_IO_PENDING, rv);
5314 EXPECT_EQ(OK, callback.WaitForResult());
5315
5316 const HttpResponseInfo* response = trans->GetResponseInfo();
5317 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505318 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005319 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5320
[email protected]90499482013-06-01 00:39:505321 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005322
5323 std::string response_data;
5324 rv = ReadTransaction(trans.get(), &response_data);
5325 EXPECT_EQ(OK, rv);
5326 EXPECT_EQ("hello world", response_data);
5327
5328 // Empty the current queue. This is necessary because idle sockets are
5329 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345330 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005331
5332 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505333 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005334
5335 // Now start the second transaction, which should reuse the previous socket.
5336
[email protected]90499482013-06-01 00:39:505337 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005338
[email protected]49639fa2011-12-20 23:22:415339 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005340
5341 EXPECT_EQ(ERR_IO_PENDING, rv);
5342 EXPECT_EQ(OK, callback.WaitForResult());
5343
5344 response = trans->GetResponseInfo();
5345 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505346 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005347 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5348
[email protected]90499482013-06-01 00:39:505349 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005350
5351 rv = ReadTransaction(trans.get(), &response_data);
5352 EXPECT_EQ(OK, rv);
5353 EXPECT_EQ("hello world", response_data);
5354
5355 // Empty the current queue. This is necessary because idle sockets are
5356 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345357 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005358
5359 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505360 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005361}
5362
[email protected]b4404c02009-04-10 16:38:525363// Make sure that we recycle a socket after a zero-length response.
5364// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025365TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425366 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525367 request.method = "GET";
bncce36dca22015-04-21 22:11:235368 request.url = GURL(
5369 "http://www.example.org/csi?v=3&s=web&action=&"
5370 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5371 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5372 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525373 request.load_flags = 0;
5374
[email protected]bb88e1d32013-05-03 23:11:075375 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275376
[email protected]262eec82013-03-19 21:01:365377 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505378 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275379
[email protected]b4404c02009-04-10 16:38:525380 MockRead data_reads[] = {
5381 MockRead("HTTP/1.1 204 No Content\r\n"
5382 "Content-Length: 0\r\n"
5383 "Content-Type: text/html\r\n\r\n"),
5384 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065385 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525386 };
5387
[email protected]31a2bfe2010-02-09 08:03:395388 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075389 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525390
[email protected]49639fa2011-12-20 23:22:415391 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525392
[email protected]49639fa2011-12-20 23:22:415393 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425394 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525395
5396 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425397 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525398
[email protected]1c773ea12009-04-28 19:58:425399 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505400 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525401
[email protected]90499482013-06-01 00:39:505402 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525403 std::string status_line = response->headers->GetStatusLine();
5404 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5405
[email protected]90499482013-06-01 00:39:505406 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525407
5408 std::string response_data;
5409 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425410 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525411 EXPECT_EQ("", response_data);
5412
5413 // Empty the current queue. This is necessary because idle sockets are
5414 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345415 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525416
5417 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505418 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525419}
5420
[email protected]23e482282013-06-14 16:08:025421TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065422 ScopedVector<UploadElementReader> element_readers;
5423 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075424 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275425
[email protected]1c773ea12009-04-28 19:58:425426 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515427 // Transaction 1: a GET request that succeeds. The socket is recycled
5428 // after use.
5429 request[0].method = "GET";
5430 request[0].url = GURL("http://www.google.com/");
5431 request[0].load_flags = 0;
5432 // Transaction 2: a POST request. Reuses the socket kept alive from
5433 // transaction 1. The first attempts fails when writing the POST data.
5434 // This causes the transaction to retry with a new socket. The second
5435 // attempt succeeds.
5436 request[1].method = "POST";
5437 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275438 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515439 request[1].load_flags = 0;
5440
[email protected]bb88e1d32013-05-03 23:11:075441 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515442
5443 // The first socket is used for transaction 1 and the first attempt of
5444 // transaction 2.
5445
5446 // The response of transaction 1.
5447 MockRead data_reads1[] = {
5448 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5449 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065450 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515451 };
5452 // The mock write results of transaction 1 and the first attempt of
5453 // transaction 2.
5454 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065455 MockWrite(SYNCHRONOUS, 64), // GET
5456 MockWrite(SYNCHRONOUS, 93), // POST
5457 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515458 };
[email protected]31a2bfe2010-02-09 08:03:395459 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5460 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515461
5462 // The second socket is used for the second attempt of transaction 2.
5463
5464 // The response of transaction 2.
5465 MockRead data_reads2[] = {
5466 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5467 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065468 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515469 };
5470 // The mock write results of the second attempt of transaction 2.
5471 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065472 MockWrite(SYNCHRONOUS, 93), // POST
5473 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515474 };
[email protected]31a2bfe2010-02-09 08:03:395475 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5476 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515477
[email protected]bb88e1d32013-05-03 23:11:075478 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5479 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515480
thestig9d3bb0c2015-01-24 00:49:515481 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515482 "hello world", "welcome"
5483 };
5484
5485 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425486 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505487 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515488
[email protected]49639fa2011-12-20 23:22:415489 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515490
[email protected]49639fa2011-12-20 23:22:415491 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425492 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515493
5494 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425495 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515496
[email protected]1c773ea12009-04-28 19:58:425497 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505498 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515499
[email protected]90499482013-06-01 00:39:505500 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515501 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5502
5503 std::string response_data;
5504 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425505 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515506 EXPECT_EQ(kExpectedResponseData[i], response_data);
5507 }
5508}
[email protected]f9ee6b52008-11-08 06:46:235509
5510// Test the request-challenge-retry sequence for basic auth when there is
5511// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165512// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025513TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425514 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235515 request.method = "GET";
bncce36dca22015-04-21 22:11:235516 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415517 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295518
[email protected]3fe8d2f82013-10-17 08:56:075519 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275520 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415521 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275522
[email protected]a97cca42009-08-14 01:00:295523 // The password contains an escaped character -- for this test to pass it
5524 // will need to be unescaped by HttpNetworkTransaction.
5525 EXPECT_EQ("b%40r", request.url.password());
5526
[email protected]f9ee6b52008-11-08 06:46:235527 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235528 MockWrite(
5529 "GET / HTTP/1.1\r\n"
5530 "Host: www.example.org\r\n"
5531 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235532 };
5533
5534 MockRead data_reads1[] = {
5535 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5536 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5537 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065538 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235539 };
5540
[email protected]2262e3a2012-05-22 16:08:165541 // After the challenge above, the transaction will be restarted using the
5542 // identity from the url (foo, b@r) to answer the challenge.
5543 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235544 MockWrite(
5545 "GET / HTTP/1.1\r\n"
5546 "Host: www.example.org\r\n"
5547 "Connection: keep-alive\r\n"
5548 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165549 };
5550
5551 MockRead data_reads2[] = {
5552 MockRead("HTTP/1.0 200 OK\r\n"),
5553 MockRead("Content-Length: 100\r\n\r\n"),
5554 MockRead(SYNCHRONOUS, OK),
5555 };
5556
[email protected]31a2bfe2010-02-09 08:03:395557 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5558 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165559 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5560 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075561 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5562 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235563
[email protected]49639fa2011-12-20 23:22:415564 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415565 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425566 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235567 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425568 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165569 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5570
5571 TestCompletionCallback callback2;
5572 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5573 EXPECT_EQ(ERR_IO_PENDING, rv);
5574 rv = callback2.WaitForResult();
5575 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225576 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5577
[email protected]2262e3a2012-05-22 16:08:165578 const HttpResponseInfo* response = trans->GetResponseInfo();
5579 ASSERT_TRUE(response != NULL);
5580
5581 // There is no challenge info, since the identity in URL worked.
5582 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5583
5584 EXPECT_EQ(100, response->headers->GetContentLength());
5585
5586 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345587 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165588}
5589
5590// Test the request-challenge-retry sequence for basic auth when there is an
5591// incorrect identity in the URL. The identity from the URL should be used only
5592// once.
[email protected]23e482282013-06-14 16:08:025593TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165594 HttpRequestInfo request;
5595 request.method = "GET";
5596 // Note: the URL has a username:password in it. The password "baz" is
5597 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:235598 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:165599
5600 request.load_flags = LOAD_NORMAL;
5601
[email protected]3fe8d2f82013-10-17 08:56:075602 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165603 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415604 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165605
5606 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235607 MockWrite(
5608 "GET / HTTP/1.1\r\n"
5609 "Host: www.example.org\r\n"
5610 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165611 };
5612
5613 MockRead data_reads1[] = {
5614 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5615 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5616 MockRead("Content-Length: 10\r\n\r\n"),
5617 MockRead(SYNCHRONOUS, ERR_FAILED),
5618 };
5619
5620 // After the challenge above, the transaction will be restarted using the
5621 // identity from the url (foo, baz) to answer the challenge.
5622 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235623 MockWrite(
5624 "GET / HTTP/1.1\r\n"
5625 "Host: www.example.org\r\n"
5626 "Connection: keep-alive\r\n"
5627 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165628 };
5629
5630 MockRead data_reads2[] = {
5631 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5632 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5633 MockRead("Content-Length: 10\r\n\r\n"),
5634 MockRead(SYNCHRONOUS, ERR_FAILED),
5635 };
5636
5637 // After the challenge above, the transaction will be restarted using the
5638 // identity supplied by the user (foo, bar) to answer the challenge.
5639 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235640 MockWrite(
5641 "GET / HTTP/1.1\r\n"
5642 "Host: www.example.org\r\n"
5643 "Connection: keep-alive\r\n"
5644 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165645 };
5646
5647 MockRead data_reads3[] = {
5648 MockRead("HTTP/1.0 200 OK\r\n"),
5649 MockRead("Content-Length: 100\r\n\r\n"),
5650 MockRead(SYNCHRONOUS, OK),
5651 };
5652
5653 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5654 data_writes1, arraysize(data_writes1));
5655 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5656 data_writes2, arraysize(data_writes2));
5657 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5658 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075659 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5660 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5661 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165662
5663 TestCompletionCallback callback1;
5664
5665 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5666 EXPECT_EQ(ERR_IO_PENDING, rv);
5667
5668 rv = callback1.WaitForResult();
5669 EXPECT_EQ(OK, rv);
5670
5671 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5672 TestCompletionCallback callback2;
5673 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5674 EXPECT_EQ(ERR_IO_PENDING, rv);
5675 rv = callback2.WaitForResult();
5676 EXPECT_EQ(OK, rv);
5677 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5678
5679 const HttpResponseInfo* response = trans->GetResponseInfo();
5680 ASSERT_TRUE(response != NULL);
5681 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5682
5683 TestCompletionCallback callback3;
5684 rv = trans->RestartWithAuth(
5685 AuthCredentials(kFoo, kBar), callback3.callback());
5686 EXPECT_EQ(ERR_IO_PENDING, rv);
5687 rv = callback3.WaitForResult();
5688 EXPECT_EQ(OK, rv);
5689 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5690
5691 response = trans->GetResponseInfo();
5692 ASSERT_TRUE(response != NULL);
5693
5694 // There is no challenge info, since the identity worked.
5695 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5696
5697 EXPECT_EQ(100, response->headers->GetContentLength());
5698
[email protected]ea9dc9a2009-09-05 00:43:325699 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345700 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325701}
5702
[email protected]2217aa22013-10-11 03:03:545703
5704// Test the request-challenge-retry sequence for basic auth when there is a
5705// correct identity in the URL, but its use is being suppressed. The identity
5706// from the URL should never be used.
5707TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5708 HttpRequestInfo request;
5709 request.method = "GET";
bncce36dca22015-04-21 22:11:235710 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:545711 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5712
[email protected]3fe8d2f82013-10-17 08:56:075713 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545714 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415715 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545716
5717 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235718 MockWrite(
5719 "GET / HTTP/1.1\r\n"
5720 "Host: www.example.org\r\n"
5721 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545722 };
5723
5724 MockRead data_reads1[] = {
5725 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5726 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5727 MockRead("Content-Length: 10\r\n\r\n"),
5728 MockRead(SYNCHRONOUS, ERR_FAILED),
5729 };
5730
5731 // After the challenge above, the transaction will be restarted using the
5732 // identity supplied by the user, not the one in the URL, to answer the
5733 // challenge.
5734 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235735 MockWrite(
5736 "GET / HTTP/1.1\r\n"
5737 "Host: www.example.org\r\n"
5738 "Connection: keep-alive\r\n"
5739 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545740 };
5741
5742 MockRead data_reads3[] = {
5743 MockRead("HTTP/1.0 200 OK\r\n"),
5744 MockRead("Content-Length: 100\r\n\r\n"),
5745 MockRead(SYNCHRONOUS, OK),
5746 };
5747
5748 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5749 data_writes1, arraysize(data_writes1));
5750 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5751 data_writes3, arraysize(data_writes3));
5752 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5753 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5754
5755 TestCompletionCallback callback1;
5756 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5757 EXPECT_EQ(ERR_IO_PENDING, rv);
5758 rv = callback1.WaitForResult();
5759 EXPECT_EQ(OK, rv);
5760 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5761
5762 const HttpResponseInfo* response = trans->GetResponseInfo();
5763 ASSERT_TRUE(response != NULL);
5764 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5765
5766 TestCompletionCallback callback3;
5767 rv = trans->RestartWithAuth(
5768 AuthCredentials(kFoo, kBar), callback3.callback());
5769 EXPECT_EQ(ERR_IO_PENDING, rv);
5770 rv = callback3.WaitForResult();
5771 EXPECT_EQ(OK, rv);
5772 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5773
5774 response = trans->GetResponseInfo();
5775 ASSERT_TRUE(response != NULL);
5776
5777 // There is no challenge info, since the identity worked.
5778 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5779 EXPECT_EQ(100, response->headers->GetContentLength());
5780
5781 // Empty the current queue.
5782 base::MessageLoop::current()->RunUntilIdle();
5783}
5784
[email protected]f9ee6b52008-11-08 06:46:235785// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025786TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075787 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235788
5789 // Transaction 1: authenticate (foo, bar) on MyRealm1
5790 {
[email protected]1c773ea12009-04-28 19:58:425791 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235792 request.method = "GET";
bncce36dca22015-04-21 22:11:235793 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:235794 request.load_flags = 0;
5795
[email protected]262eec82013-03-19 21:01:365796 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505797 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275798
[email protected]f9ee6b52008-11-08 06:46:235799 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235800 MockWrite(
5801 "GET /x/y/z HTTP/1.1\r\n"
5802 "Host: www.example.org\r\n"
5803 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235804 };
5805
5806 MockRead data_reads1[] = {
5807 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5808 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5809 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065810 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235811 };
5812
5813 // Resend with authorization (username=foo, password=bar)
5814 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235815 MockWrite(
5816 "GET /x/y/z HTTP/1.1\r\n"
5817 "Host: www.example.org\r\n"
5818 "Connection: keep-alive\r\n"
5819 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235820 };
5821
5822 // Sever accepts the authorization.
5823 MockRead data_reads2[] = {
5824 MockRead("HTTP/1.0 200 OK\r\n"),
5825 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065826 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235827 };
5828
[email protected]31a2bfe2010-02-09 08:03:395829 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5830 data_writes1, arraysize(data_writes1));
5831 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5832 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075833 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5834 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235835
[email protected]49639fa2011-12-20 23:22:415836 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235837
[email protected]49639fa2011-12-20 23:22:415838 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425839 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235840
5841 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425842 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235843
[email protected]1c773ea12009-04-28 19:58:425844 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505845 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045846 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235847
[email protected]49639fa2011-12-20 23:22:415848 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235849
[email protected]49639fa2011-12-20 23:22:415850 rv = trans->RestartWithAuth(
5851 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425852 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235853
5854 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425855 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235856
5857 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505858 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235859 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5860 EXPECT_EQ(100, response->headers->GetContentLength());
5861 }
5862
5863 // ------------------------------------------------------------------------
5864
5865 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5866 {
[email protected]1c773ea12009-04-28 19:58:425867 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235868 request.method = "GET";
5869 // Note that Transaction 1 was at /x/y/z, so this is in the same
5870 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:235871 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:235872 request.load_flags = 0;
5873
[email protected]262eec82013-03-19 21:01:365874 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505875 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275876
[email protected]f9ee6b52008-11-08 06:46:235877 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235878 MockWrite(
5879 "GET /x/y/a/b HTTP/1.1\r\n"
5880 "Host: www.example.org\r\n"
5881 "Connection: keep-alive\r\n"
5882 // Send preemptive authorization for MyRealm1
5883 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235884 };
5885
5886 // The server didn't like the preemptive authorization, and
5887 // challenges us for a different realm (MyRealm2).
5888 MockRead data_reads1[] = {
5889 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5890 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5891 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065892 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235893 };
5894
5895 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5896 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235897 MockWrite(
5898 "GET /x/y/a/b HTTP/1.1\r\n"
5899 "Host: www.example.org\r\n"
5900 "Connection: keep-alive\r\n"
5901 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235902 };
5903
5904 // Sever accepts the authorization.
5905 MockRead data_reads2[] = {
5906 MockRead("HTTP/1.0 200 OK\r\n"),
5907 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065908 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235909 };
5910
[email protected]31a2bfe2010-02-09 08:03:395911 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5912 data_writes1, arraysize(data_writes1));
5913 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5914 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075915 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5916 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235917
[email protected]49639fa2011-12-20 23:22:415918 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235919
[email protected]49639fa2011-12-20 23:22:415920 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425921 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235922
5923 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425924 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235925
[email protected]1c773ea12009-04-28 19:58:425926 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505927 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045928 ASSERT_TRUE(response->auth_challenge.get());
5929 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:235930 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:045931 response->auth_challenge->challenger.ToString());
5932 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5933 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235934
[email protected]49639fa2011-12-20 23:22:415935 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235936
[email protected]49639fa2011-12-20 23:22:415937 rv = trans->RestartWithAuth(
5938 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425939 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235940
5941 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425942 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235943
5944 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505945 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235946 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5947 EXPECT_EQ(100, response->headers->GetContentLength());
5948 }
5949
5950 // ------------------------------------------------------------------------
5951
5952 // Transaction 3: Resend a request in MyRealm's protection space --
5953 // succeed with preemptive authorization.
5954 {
[email protected]1c773ea12009-04-28 19:58:425955 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235956 request.method = "GET";
bncce36dca22015-04-21 22:11:235957 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:235958 request.load_flags = 0;
5959
[email protected]262eec82013-03-19 21:01:365960 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505961 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275962
[email protected]f9ee6b52008-11-08 06:46:235963 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235964 MockWrite(
5965 "GET /x/y/z2 HTTP/1.1\r\n"
5966 "Host: www.example.org\r\n"
5967 "Connection: keep-alive\r\n"
5968 // The authorization for MyRealm1 gets sent preemptively
5969 // (since the url is in the same protection space)
5970 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235971 };
5972
5973 // Sever accepts the preemptive authorization
5974 MockRead data_reads1[] = {
5975 MockRead("HTTP/1.0 200 OK\r\n"),
5976 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065977 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235978 };
5979
[email protected]31a2bfe2010-02-09 08:03:395980 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5981 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075982 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235983
[email protected]49639fa2011-12-20 23:22:415984 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235985
[email protected]49639fa2011-12-20 23:22:415986 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425987 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235988
5989 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425990 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235991
[email protected]1c773ea12009-04-28 19:58:425992 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505993 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235994
5995 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5996 EXPECT_EQ(100, response->headers->GetContentLength());
5997 }
5998
5999 // ------------------------------------------------------------------------
6000
6001 // Transaction 4: request another URL in MyRealm (however the
6002 // url is not known to belong to the protection space, so no pre-auth).
6003 {
[email protected]1c773ea12009-04-28 19:58:426004 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236005 request.method = "GET";
bncce36dca22015-04-21 22:11:236006 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:236007 request.load_flags = 0;
6008
[email protected]262eec82013-03-19 21:01:366009 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506010 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276011
[email protected]f9ee6b52008-11-08 06:46:236012 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236013 MockWrite(
6014 "GET /x/1 HTTP/1.1\r\n"
6015 "Host: www.example.org\r\n"
6016 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236017 };
6018
6019 MockRead data_reads1[] = {
6020 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6021 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6022 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066023 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236024 };
6025
6026 // Resend with authorization from MyRealm's cache.
6027 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236028 MockWrite(
6029 "GET /x/1 HTTP/1.1\r\n"
6030 "Host: www.example.org\r\n"
6031 "Connection: keep-alive\r\n"
6032 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236033 };
6034
6035 // Sever accepts the authorization.
6036 MockRead data_reads2[] = {
6037 MockRead("HTTP/1.0 200 OK\r\n"),
6038 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066039 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236040 };
6041
[email protected]31a2bfe2010-02-09 08:03:396042 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6043 data_writes1, arraysize(data_writes1));
6044 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6045 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076046 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6047 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236048
[email protected]49639fa2011-12-20 23:22:416049 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236050
[email protected]49639fa2011-12-20 23:22:416051 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426052 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236053
6054 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426055 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236056
[email protected]0757e7702009-03-27 04:00:226057 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416058 TestCompletionCallback callback2;
6059 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426060 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226061 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426062 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226063 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6064
[email protected]1c773ea12009-04-28 19:58:426065 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506066 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236067 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6068 EXPECT_EQ(100, response->headers->GetContentLength());
6069 }
6070
6071 // ------------------------------------------------------------------------
6072
6073 // Transaction 5: request a URL in MyRealm, but the server rejects the
6074 // cached identity. Should invalidate and re-prompt.
6075 {
[email protected]1c773ea12009-04-28 19:58:426076 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236077 request.method = "GET";
bncce36dca22015-04-21 22:11:236078 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:236079 request.load_flags = 0;
6080
[email protected]262eec82013-03-19 21:01:366081 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506082 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276083
[email protected]f9ee6b52008-11-08 06:46:236084 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236085 MockWrite(
6086 "GET /p/q/t HTTP/1.1\r\n"
6087 "Host: www.example.org\r\n"
6088 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236089 };
6090
6091 MockRead data_reads1[] = {
6092 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6093 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6094 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066095 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236096 };
6097
6098 // Resend with authorization from cache for MyRealm.
6099 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236100 MockWrite(
6101 "GET /p/q/t HTTP/1.1\r\n"
6102 "Host: www.example.org\r\n"
6103 "Connection: keep-alive\r\n"
6104 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236105 };
6106
6107 // Sever rejects the authorization.
6108 MockRead data_reads2[] = {
6109 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6110 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6111 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066112 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236113 };
6114
6115 // At this point we should prompt for new credentials for MyRealm.
6116 // Restart with username=foo3, password=foo4.
6117 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236118 MockWrite(
6119 "GET /p/q/t HTTP/1.1\r\n"
6120 "Host: www.example.org\r\n"
6121 "Connection: keep-alive\r\n"
6122 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236123 };
6124
6125 // Sever accepts the authorization.
6126 MockRead data_reads3[] = {
6127 MockRead("HTTP/1.0 200 OK\r\n"),
6128 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066129 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236130 };
6131
[email protected]31a2bfe2010-02-09 08:03:396132 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6133 data_writes1, arraysize(data_writes1));
6134 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6135 data_writes2, arraysize(data_writes2));
6136 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6137 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076138 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6139 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6140 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236141
[email protected]49639fa2011-12-20 23:22:416142 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236143
[email protected]49639fa2011-12-20 23:22:416144 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426145 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236146
6147 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426148 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236149
[email protected]0757e7702009-03-27 04:00:226150 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416151 TestCompletionCallback callback2;
6152 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426153 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226154 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426155 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226156 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6157
[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]79cb5c12011-09-12 13:12:046160 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236161
[email protected]49639fa2011-12-20 23:22:416162 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236163
[email protected]49639fa2011-12-20 23:22:416164 rv = trans->RestartWithAuth(
6165 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426166 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236167
[email protected]0757e7702009-03-27 04:00:226168 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426169 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236170
6171 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506172 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236173 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6174 EXPECT_EQ(100, response->headers->GetContentLength());
6175 }
6176}
[email protected]89ceba9a2009-03-21 03:46:066177
[email protected]3c32c5f2010-05-18 15:18:126178// Tests that nonce count increments when multiple auth attempts
6179// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026180TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446181 HttpAuthHandlerDigest::Factory* digest_factory =
6182 new HttpAuthHandlerDigest::Factory();
6183 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6184 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6185 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076186 session_deps_.http_auth_handler_factory.reset(digest_factory);
6187 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126188
6189 // Transaction 1: authenticate (foo, bar) on MyRealm1
6190 {
[email protected]3c32c5f2010-05-18 15:18:126191 HttpRequestInfo request;
6192 request.method = "GET";
bncce36dca22015-04-21 22:11:236193 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126194 request.load_flags = 0;
6195
[email protected]262eec82013-03-19 21:01:366196 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506197 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276198
[email protected]3c32c5f2010-05-18 15:18:126199 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236200 MockWrite(
6201 "GET /x/y/z HTTP/1.1\r\n"
6202 "Host: www.example.org\r\n"
6203 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126204 };
6205
6206 MockRead data_reads1[] = {
6207 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6208 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6209 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066210 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126211 };
6212
6213 // Resend with authorization (username=foo, password=bar)
6214 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236215 MockWrite(
6216 "GET /x/y/z HTTP/1.1\r\n"
6217 "Host: www.example.org\r\n"
6218 "Connection: keep-alive\r\n"
6219 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6220 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6221 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6222 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126223 };
6224
6225 // Sever accepts the authorization.
6226 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:086227 MockRead("HTTP/1.0 200 OK\r\n"),
6228 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126229 };
6230
6231 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6232 data_writes1, arraysize(data_writes1));
6233 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6234 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076235 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6236 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126237
[email protected]49639fa2011-12-20 23:22:416238 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126239
[email protected]49639fa2011-12-20 23:22:416240 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126241 EXPECT_EQ(ERR_IO_PENDING, rv);
6242
6243 rv = callback1.WaitForResult();
6244 EXPECT_EQ(OK, rv);
6245
6246 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506247 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046248 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126249
[email protected]49639fa2011-12-20 23:22:416250 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126251
[email protected]49639fa2011-12-20 23:22:416252 rv = trans->RestartWithAuth(
6253 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126254 EXPECT_EQ(ERR_IO_PENDING, rv);
6255
6256 rv = callback2.WaitForResult();
6257 EXPECT_EQ(OK, rv);
6258
6259 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506260 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126261 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6262 }
6263
6264 // ------------------------------------------------------------------------
6265
6266 // Transaction 2: Request another resource in digestive's protection space.
6267 // This will preemptively add an Authorization header which should have an
6268 // "nc" value of 2 (as compared to 1 in the first use.
6269 {
[email protected]3c32c5f2010-05-18 15:18:126270 HttpRequestInfo request;
6271 request.method = "GET";
6272 // Note that Transaction 1 was at /x/y/z, so this is in the same
6273 // protection space as digest.
bncce36dca22015-04-21 22:11:236274 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126275 request.load_flags = 0;
6276
[email protected]262eec82013-03-19 21:01:366277 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506278 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276279
[email protected]3c32c5f2010-05-18 15:18:126280 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236281 MockWrite(
6282 "GET /x/y/a/b HTTP/1.1\r\n"
6283 "Host: www.example.org\r\n"
6284 "Connection: keep-alive\r\n"
6285 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6286 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6287 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6288 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126289 };
6290
6291 // Sever accepts the authorization.
6292 MockRead data_reads1[] = {
6293 MockRead("HTTP/1.0 200 OK\r\n"),
6294 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066295 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126296 };
6297
6298 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6299 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076300 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126301
[email protected]49639fa2011-12-20 23:22:416302 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126303
[email protected]49639fa2011-12-20 23:22:416304 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126305 EXPECT_EQ(ERR_IO_PENDING, rv);
6306
6307 rv = callback1.WaitForResult();
6308 EXPECT_EQ(OK, rv);
6309
6310 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506311 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126312 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6313 }
6314}
6315
[email protected]89ceba9a2009-03-21 03:46:066316// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026317TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066318 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:076319 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406320 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416321 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066322
6323 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066324 trans->read_buf_ = new IOBuffer(15);
6325 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206326 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066327
6328 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146329 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576330 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086331 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576332 response->response_time = base::Time::Now();
6333 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066334
6335 { // Setup state for response_.vary_data
6336 HttpRequestInfo request;
6337 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6338 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276339 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436340 request.extra_headers.SetHeader("Foo", "1");
6341 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506342 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066343 }
6344
6345 // Cause the above state to be reset.
6346 trans->ResetStateForRestart();
6347
6348 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076349 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066350 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206351 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576352 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6353 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046354 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086355 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576356 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066357}
6358
[email protected]bacff652009-03-31 17:50:336359// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026360TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336361 HttpRequestInfo request;
6362 request.method = "GET";
bncce36dca22015-04-21 22:11:236363 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336364 request.load_flags = 0;
6365
[email protected]3fe8d2f82013-10-17 08:56:076366 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276367 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416368 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276369
[email protected]bacff652009-03-31 17:50:336370 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236371 MockWrite(
6372 "GET / HTTP/1.1\r\n"
6373 "Host: www.example.org\r\n"
6374 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336375 };
6376
6377 MockRead data_reads[] = {
6378 MockRead("HTTP/1.0 200 OK\r\n"),
6379 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6380 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066381 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336382 };
6383
[email protected]5ecc992a42009-11-11 01:41:596384 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396385 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6386 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066387 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6388 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336389
[email protected]bb88e1d32013-05-03 23:11:076390 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6391 session_deps_.socket_factory->AddSocketDataProvider(&data);
6392 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6393 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336394
[email protected]49639fa2011-12-20 23:22:416395 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336396
[email protected]49639fa2011-12-20 23:22:416397 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336398 EXPECT_EQ(ERR_IO_PENDING, rv);
6399
6400 rv = callback.WaitForResult();
6401 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6402
[email protected]49639fa2011-12-20 23:22:416403 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336404 EXPECT_EQ(ERR_IO_PENDING, rv);
6405
6406 rv = callback.WaitForResult();
6407 EXPECT_EQ(OK, rv);
6408
6409 const HttpResponseInfo* response = trans->GetResponseInfo();
6410
[email protected]fe2255a2011-09-20 19:37:506411 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336412 EXPECT_EQ(100, response->headers->GetContentLength());
6413}
6414
6415// Test HTTPS connections to a site with a bad certificate, going through a
6416// proxy
[email protected]23e482282013-06-14 16:08:026417TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:076418 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:336419
6420 HttpRequestInfo request;
6421 request.method = "GET";
bncce36dca22015-04-21 22:11:236422 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336423 request.load_flags = 0;
6424
6425 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:236426 MockWrite(
6427 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6428 "Host: www.example.org\r\n"
6429 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336430 };
6431
6432 MockRead proxy_reads[] = {
6433 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066434 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336435 };
6436
6437 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236438 MockWrite(
6439 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6440 "Host: www.example.org\r\n"
6441 "Proxy-Connection: keep-alive\r\n\r\n"),
6442 MockWrite(
6443 "GET / HTTP/1.1\r\n"
6444 "Host: www.example.org\r\n"
6445 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336446 };
6447
6448 MockRead data_reads[] = {
6449 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6450 MockRead("HTTP/1.0 200 OK\r\n"),
6451 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6452 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066453 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336454 };
6455
[email protected]31a2bfe2010-02-09 08:03:396456 StaticSocketDataProvider ssl_bad_certificate(
6457 proxy_reads, arraysize(proxy_reads),
6458 proxy_writes, arraysize(proxy_writes));
6459 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6460 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066461 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6462 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336463
[email protected]bb88e1d32013-05-03 23:11:076464 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6465 session_deps_.socket_factory->AddSocketDataProvider(&data);
6466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6467 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336468
[email protected]49639fa2011-12-20 23:22:416469 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336470
6471 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076472 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336473
[email protected]3fe8d2f82013-10-17 08:56:076474 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406475 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416476 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336477
[email protected]49639fa2011-12-20 23:22:416478 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336479 EXPECT_EQ(ERR_IO_PENDING, rv);
6480
6481 rv = callback.WaitForResult();
6482 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6483
[email protected]49639fa2011-12-20 23:22:416484 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336485 EXPECT_EQ(ERR_IO_PENDING, rv);
6486
6487 rv = callback.WaitForResult();
6488 EXPECT_EQ(OK, rv);
6489
6490 const HttpResponseInfo* response = trans->GetResponseInfo();
6491
[email protected]fe2255a2011-09-20 19:37:506492 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336493 EXPECT_EQ(100, response->headers->GetContentLength());
6494 }
6495}
6496
[email protected]2df19bb2010-08-25 20:13:466497
6498// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026499TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076500 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206501 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516502 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076503 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466504
6505 HttpRequestInfo request;
6506 request.method = "GET";
bncce36dca22015-04-21 22:11:236507 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466508 request.load_flags = 0;
6509
6510 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236511 MockWrite(
6512 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6513 "Host: www.example.org\r\n"
6514 "Proxy-Connection: keep-alive\r\n\r\n"),
6515 MockWrite(
6516 "GET / HTTP/1.1\r\n"
6517 "Host: www.example.org\r\n"
6518 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466519 };
6520
6521 MockRead data_reads[] = {
6522 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6523 MockRead("HTTP/1.1 200 OK\r\n"),
6524 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6525 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066526 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466527 };
6528
6529 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6530 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066531 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6532 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466533
[email protected]bb88e1d32013-05-03 23:11:076534 session_deps_.socket_factory->AddSocketDataProvider(&data);
6535 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6536 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466537
[email protected]49639fa2011-12-20 23:22:416538 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466539
[email protected]3fe8d2f82013-10-17 08:56:076540 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466541 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416542 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466543
[email protected]49639fa2011-12-20 23:22:416544 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466545 EXPECT_EQ(ERR_IO_PENDING, rv);
6546
6547 rv = callback.WaitForResult();
6548 EXPECT_EQ(OK, rv);
6549 const HttpResponseInfo* response = trans->GetResponseInfo();
6550
[email protected]fe2255a2011-09-20 19:37:506551 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466552
6553 EXPECT_TRUE(response->headers->IsKeepAlive());
6554 EXPECT_EQ(200, response->headers->response_code());
6555 EXPECT_EQ(100, response->headers->GetContentLength());
6556 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206557
6558 LoadTimingInfo load_timing_info;
6559 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6560 TestLoadTimingNotReusedWithPac(load_timing_info,
6561 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466562}
6563
[email protected]511f6f52010-12-17 03:58:296564// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026565TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076566 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206567 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516568 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076569 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296570
6571 HttpRequestInfo request;
6572 request.method = "GET";
bncce36dca22015-04-21 22:11:236573 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296574 request.load_flags = 0;
6575
6576 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236577 MockWrite(
6578 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6579 "Host: www.example.org\r\n"
6580 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296581 };
6582
6583 MockRead data_reads[] = {
6584 MockRead("HTTP/1.1 302 Redirect\r\n"),
6585 MockRead("Location: http://login.example.com/\r\n"),
6586 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066587 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296588 };
6589
6590 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6591 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066592 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296593
[email protected]bb88e1d32013-05-03 23:11:076594 session_deps_.socket_factory->AddSocketDataProvider(&data);
6595 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296596
[email protected]49639fa2011-12-20 23:22:416597 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296598
[email protected]3fe8d2f82013-10-17 08:56:076599 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296600 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416601 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296602
[email protected]49639fa2011-12-20 23:22:416603 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296604 EXPECT_EQ(ERR_IO_PENDING, rv);
6605
6606 rv = callback.WaitForResult();
6607 EXPECT_EQ(OK, rv);
6608 const HttpResponseInfo* response = trans->GetResponseInfo();
6609
[email protected]fe2255a2011-09-20 19:37:506610 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296611
6612 EXPECT_EQ(302, response->headers->response_code());
6613 std::string url;
6614 EXPECT_TRUE(response->headers->IsRedirect(&url));
6615 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206616
6617 // In the case of redirects from proxies, HttpNetworkTransaction returns
6618 // timing for the proxy connection instead of the connection to the host,
6619 // and no send / receive times.
6620 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6621 LoadTimingInfo load_timing_info;
6622 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6623
6624 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:296625 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:206626
6627 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6628 EXPECT_LE(load_timing_info.proxy_resolve_start,
6629 load_timing_info.proxy_resolve_end);
6630 EXPECT_LE(load_timing_info.proxy_resolve_end,
6631 load_timing_info.connect_timing.connect_start);
6632 ExpectConnectTimingHasTimes(
6633 load_timing_info.connect_timing,
6634 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6635
6636 EXPECT_TRUE(load_timing_info.send_start.is_null());
6637 EXPECT_TRUE(load_timing_info.send_end.is_null());
6638 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296639}
6640
6641// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026642TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076643 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296644 ProxyService::CreateFixed("https://proxy:70"));
6645
6646 HttpRequestInfo request;
6647 request.method = "GET";
bncce36dca22015-04-21 22:11:236648 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296649 request.load_flags = 0;
6650
lgarrona91df87f2014-12-05 00:51:346651 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236652 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206653 scoped_ptr<SpdyFrame> goaway(
6654 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296655 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136656 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6657 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296658 };
6659
6660 static const char* const kExtraHeaders[] = {
6661 "location",
6662 "http://login.example.com/",
6663 };
[email protected]ff98d7f02012-03-22 21:44:196664 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026665 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296666 arraysize(kExtraHeaders)/2, 1));
6667 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136668 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:296669 };
6670
rch8e6c6c42015-05-01 14:05:136671 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6672 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066673 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026674 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296675
[email protected]bb88e1d32013-05-03 23:11:076676 session_deps_.socket_factory->AddSocketDataProvider(&data);
6677 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296678
[email protected]49639fa2011-12-20 23:22:416679 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296680
[email protected]3fe8d2f82013-10-17 08:56:076681 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296682 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416683 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296684
[email protected]49639fa2011-12-20 23:22:416685 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296686 EXPECT_EQ(ERR_IO_PENDING, rv);
6687
6688 rv = callback.WaitForResult();
6689 EXPECT_EQ(OK, rv);
6690 const HttpResponseInfo* response = trans->GetResponseInfo();
6691
[email protected]fe2255a2011-09-20 19:37:506692 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296693
6694 EXPECT_EQ(302, response->headers->response_code());
6695 std::string url;
6696 EXPECT_TRUE(response->headers->IsRedirect(&url));
6697 EXPECT_EQ("http://login.example.com/", url);
6698}
6699
[email protected]4eddbc732012-08-09 05:40:176700// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026701TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176702 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076703 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296704 ProxyService::CreateFixed("https://proxy:70"));
6705
6706 HttpRequestInfo request;
6707 request.method = "GET";
bncce36dca22015-04-21 22:11:236708 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296709 request.load_flags = 0;
6710
6711 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236712 MockWrite(
6713 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6714 "Host: www.example.org\r\n"
6715 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296716 };
6717
6718 MockRead data_reads[] = {
6719 MockRead("HTTP/1.1 404 Not Found\r\n"),
6720 MockRead("Content-Length: 23\r\n\r\n"),
6721 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066722 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296723 };
6724
6725 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6726 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066727 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296728
[email protected]bb88e1d32013-05-03 23:11:076729 session_deps_.socket_factory->AddSocketDataProvider(&data);
6730 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296731
[email protected]49639fa2011-12-20 23:22:416732 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296733
[email protected]3fe8d2f82013-10-17 08:56:076734 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296735 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416736 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296737
[email protected]49639fa2011-12-20 23:22:416738 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296739 EXPECT_EQ(ERR_IO_PENDING, rv);
6740
6741 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176742 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296743
[email protected]4eddbc732012-08-09 05:40:176744 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296745}
6746
[email protected]4eddbc732012-08-09 05:40:176747// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026748TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176749 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076750 session_deps_.proxy_service.reset(
6751 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296752
6753 HttpRequestInfo request;
6754 request.method = "GET";
bncce36dca22015-04-21 22:11:236755 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296756 request.load_flags = 0;
6757
lgarrona91df87f2014-12-05 00:51:346758 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236759 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206760 scoped_ptr<SpdyFrame> rst(
6761 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296762 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136763 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:296764 };
6765
6766 static const char* const kExtraHeaders[] = {
6767 "location",
6768 "http://login.example.com/",
6769 };
[email protected]ff98d7f02012-03-22 21:44:196770 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026771 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296772 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196773 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026774 spdy_util_.ConstructSpdyBodyFrame(
6775 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296776 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136777 CreateMockRead(*resp.get(), 1),
6778 CreateMockRead(*body.get(), 2),
6779 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296780 };
6781
rch8e6c6c42015-05-01 14:05:136782 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6783 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066784 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026785 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296786
[email protected]bb88e1d32013-05-03 23:11:076787 session_deps_.socket_factory->AddSocketDataProvider(&data);
6788 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296789
[email protected]49639fa2011-12-20 23:22:416790 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296791
[email protected]3fe8d2f82013-10-17 08:56:076792 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296793 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416794 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296795
[email protected]49639fa2011-12-20 23:22:416796 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296797 EXPECT_EQ(ERR_IO_PENDING, rv);
6798
6799 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176800 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296801
[email protected]4eddbc732012-08-09 05:40:176802 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296803}
6804
[email protected]0c5fb722012-02-28 11:50:356805// Test the request-challenge-retry sequence for basic auth, through
6806// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026807TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356808 HttpRequestInfo request;
6809 request.method = "GET";
bncce36dca22015-04-21 22:11:236810 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:356811 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296812 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:356813
6814 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076815 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206816 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516817 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076818 session_deps_.net_log = log.bound().net_log();
6819 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356820
6821 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346822 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236823 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206824 scoped_ptr<SpdyFrame> rst(
6825 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356826
6827 // After calling trans->RestartWithAuth(), this is the request we should
6828 // be issuing -- the final header line contains the credentials.
6829 const char* const kAuthCredentials[] = {
6830 "proxy-authorization", "Basic Zm9vOmJhcg==",
6831 };
[email protected]fba2dbde2013-05-24 16:09:016832 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346833 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:236834 HostPortPair("www.example.org", 443)));
6835 // fetch https://www.example.org/ via HTTP
6836 const char get[] =
6837 "GET / HTTP/1.1\r\n"
6838 "Host: www.example.org\r\n"
6839 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196840 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026841 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356842
6843 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136844 CreateMockWrite(*req, 0, ASYNC),
6845 CreateMockWrite(*rst, 2, ASYNC),
6846 CreateMockWrite(*connect2, 3),
6847 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:356848 };
6849
6850 // The proxy responds to the connect with a 407, using a persistent
6851 // connection.
thestig9d3bb0c2015-01-24 00:49:516852 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356853 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356854 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6855 };
[email protected]745aa9c2014-06-27 02:21:296856 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6857 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356858
[email protected]23e482282013-06-14 16:08:026859 scoped_ptr<SpdyFrame> conn_resp(
6860 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356861 const char resp[] = "HTTP/1.1 200 OK\r\n"
6862 "Content-Length: 5\r\n\r\n";
6863
[email protected]ff98d7f02012-03-22 21:44:196864 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026865 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196866 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026867 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356868 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136869 CreateMockRead(*conn_auth_resp, 1, ASYNC),
6870 CreateMockRead(*conn_resp, 4, ASYNC),
6871 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
6872 CreateMockRead(*wrapped_body, 7, ASYNC),
6873 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356874 };
6875
rch8e6c6c42015-05-01 14:05:136876 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6877 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076878 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356879 // Negotiate SPDY to the proxy
6880 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026881 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076882 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356883 // Vanilla SSL to the server
6884 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076885 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356886
6887 TestCompletionCallback callback1;
6888
[email protected]262eec82013-03-19 21:01:366889 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506890 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356891
6892 int rv = trans->Start(&request, callback1.callback(), log.bound());
6893 EXPECT_EQ(ERR_IO_PENDING, rv);
6894
6895 rv = callback1.WaitForResult();
6896 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:466897 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:356898 log.GetEntries(&entries);
6899 size_t pos = ExpectLogContainsSomewhere(
6900 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6901 NetLog::PHASE_NONE);
6902 ExpectLogContainsSomewhere(
6903 entries, pos,
6904 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6905 NetLog::PHASE_NONE);
6906
6907 const HttpResponseInfo* response = trans->GetResponseInfo();
6908 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506909 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356910 EXPECT_EQ(407, response->headers->response_code());
6911 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6912 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6913 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6914
6915 TestCompletionCallback callback2;
6916
6917 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6918 callback2.callback());
6919 EXPECT_EQ(ERR_IO_PENDING, rv);
6920
6921 rv = callback2.WaitForResult();
6922 EXPECT_EQ(OK, rv);
6923
6924 response = trans->GetResponseInfo();
6925 ASSERT_TRUE(response != NULL);
6926
6927 EXPECT_TRUE(response->headers->IsKeepAlive());
6928 EXPECT_EQ(200, response->headers->response_code());
6929 EXPECT_EQ(5, response->headers->GetContentLength());
6930 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6931
6932 // The password prompt info should not be set.
6933 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6934
[email protected]029c83b62013-01-24 05:28:206935 LoadTimingInfo load_timing_info;
6936 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6937 TestLoadTimingNotReusedWithPac(load_timing_info,
6938 CONNECT_TIMING_HAS_SSL_TIMES);
6939
[email protected]0c5fb722012-02-28 11:50:356940 trans.reset();
6941 session->CloseAllConnections();
6942}
6943
[email protected]7c6f7ba2012-04-03 04:09:296944// Test that an explicitly trusted SPDY proxy can push a resource from an
6945// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026946TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296947 HttpRequestInfo request;
6948 HttpRequestInfo push_request;
6949
[email protected]7c6f7ba2012-04-03 04:09:296950 request.method = "GET";
bncce36dca22015-04-21 22:11:236951 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:296952 push_request.method = "GET";
6953 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6954
[email protected]7c6f7ba2012-04-03 04:09:296955 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076956 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206957 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516958 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076959 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506960
6961 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076962 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506963
[email protected]bb88e1d32013-05-03 23:11:076964 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296965
[email protected]cdf8f7e72013-05-23 10:56:466966 scoped_ptr<SpdyFrame> stream1_syn(
6967 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296968
6969 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136970 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296971 };
6972
6973 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026974 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296975
6976 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026977 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296978
6979 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026980 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296981 0,
6982 2,
6983 1,
6984 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436985 const char kPushedData[] = "pushed";
6986 scoped_ptr<SpdyFrame> stream2_body(
6987 spdy_util_.ConstructSpdyBodyFrame(
6988 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296989
6990 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136991 CreateMockRead(*stream1_reply, 1, ASYNC),
6992 CreateMockRead(*stream2_syn, 2, ASYNC),
6993 CreateMockRead(*stream1_body, 3, ASYNC),
6994 CreateMockRead(*stream2_body, 4, ASYNC),
6995 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:296996 };
6997
rch8e6c6c42015-05-01 14:05:136998 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6999 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077000 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:297001 // Negotiate SPDY to the proxy
7002 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027003 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077004 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:297005
[email protected]262eec82013-03-19 21:01:367006 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507007 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:297008 TestCompletionCallback callback;
7009 int rv = trans->Start(&request, callback.callback(), log.bound());
7010 EXPECT_EQ(ERR_IO_PENDING, rv);
7011
7012 rv = callback.WaitForResult();
7013 EXPECT_EQ(OK, rv);
7014 const HttpResponseInfo* response = trans->GetResponseInfo();
7015
[email protected]262eec82013-03-19 21:01:367016 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:507017 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7018 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:297019 EXPECT_EQ(ERR_IO_PENDING, rv);
7020
7021 rv = callback.WaitForResult();
7022 EXPECT_EQ(OK, rv);
7023 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
7024
7025 ASSERT_TRUE(response != NULL);
7026 EXPECT_TRUE(response->headers->IsKeepAlive());
7027
7028 EXPECT_EQ(200, response->headers->response_code());
7029 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7030
7031 std::string response_data;
7032 rv = ReadTransaction(trans.get(), &response_data);
7033 EXPECT_EQ(OK, rv);
7034 EXPECT_EQ("hello!", response_data);
7035
[email protected]029c83b62013-01-24 05:28:207036 LoadTimingInfo load_timing_info;
7037 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7038 TestLoadTimingNotReusedWithPac(load_timing_info,
7039 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7040
[email protected]7c6f7ba2012-04-03 04:09:297041 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:507042 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:297043 EXPECT_EQ(200, push_response->headers->response_code());
7044
7045 rv = ReadTransaction(push_trans.get(), &response_data);
7046 EXPECT_EQ(OK, rv);
7047 EXPECT_EQ("pushed", response_data);
7048
[email protected]029c83b62013-01-24 05:28:207049 LoadTimingInfo push_load_timing_info;
7050 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
7051 TestLoadTimingReusedWithPac(push_load_timing_info);
7052 // The transactions should share a socket ID, despite being for different
7053 // origins.
7054 EXPECT_EQ(load_timing_info.socket_log_id,
7055 push_load_timing_info.socket_log_id);
7056
[email protected]7c6f7ba2012-04-03 04:09:297057 trans.reset();
7058 push_trans.reset();
7059 session->CloseAllConnections();
7060}
7061
[email protected]8c843192012-04-05 07:15:007062// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:027063TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:007064 HttpRequestInfo request;
7065
7066 request.method = "GET";
bncce36dca22015-04-21 22:11:237067 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:007068
[email protected]8c843192012-04-05 07:15:007069 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:077070 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:007071 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:517072 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077073 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507074
7075 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077076 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507077
[email protected]bb88e1d32013-05-03 23:11:077078 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:007079
[email protected]cdf8f7e72013-05-23 10:56:467080 scoped_ptr<SpdyFrame> stream1_syn(
7081 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:007082
7083 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207084 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007085
7086 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137087 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007088 };
7089
7090 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027091 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007092
7093 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027094 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007095
7096 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027097 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:007098 0,
7099 2,
7100 1,
7101 "https://www.another-origin.com/foo.dat"));
7102
7103 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137104 CreateMockRead(*stream1_reply, 1, ASYNC),
7105 CreateMockRead(*stream2_syn, 2, ASYNC),
7106 CreateMockRead(*stream1_body, 4, ASYNC),
7107 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007108 };
7109
rch8e6c6c42015-05-01 14:05:137110 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7111 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077112 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007113 // Negotiate SPDY to the proxy
7114 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027115 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077116 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007117
[email protected]262eec82013-03-19 21:01:367118 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507119 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007120 TestCompletionCallback callback;
7121 int rv = trans->Start(&request, callback.callback(), log.bound());
7122 EXPECT_EQ(ERR_IO_PENDING, rv);
7123
7124 rv = callback.WaitForResult();
7125 EXPECT_EQ(OK, rv);
7126 const HttpResponseInfo* response = trans->GetResponseInfo();
7127
7128 ASSERT_TRUE(response != NULL);
7129 EXPECT_TRUE(response->headers->IsKeepAlive());
7130
7131 EXPECT_EQ(200, response->headers->response_code());
7132 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7133
7134 std::string response_data;
7135 rv = ReadTransaction(trans.get(), &response_data);
7136 EXPECT_EQ(OK, rv);
7137 EXPECT_EQ("hello!", response_data);
7138
7139 trans.reset();
7140 session->CloseAllConnections();
7141}
7142
[email protected]2df19bb2010-08-25 20:13:467143// Test HTTPS connections to a site with a bad certificate, going through an
7144// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027145TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:077146 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:117147 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:467148
7149 HttpRequestInfo request;
7150 request.method = "GET";
bncce36dca22015-04-21 22:11:237151 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467152 request.load_flags = 0;
7153
7154 // Attempt to fetch the URL from a server with a bad cert
7155 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237156 MockWrite(
7157 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7158 "Host: www.example.org\r\n"
7159 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467160 };
7161
7162 MockRead bad_cert_reads[] = {
7163 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067164 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467165 };
7166
7167 // Attempt to fetch the URL with a good cert
7168 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237169 MockWrite(
7170 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7171 "Host: www.example.org\r\n"
7172 "Proxy-Connection: keep-alive\r\n\r\n"),
7173 MockWrite(
7174 "GET / HTTP/1.1\r\n"
7175 "Host: www.example.org\r\n"
7176 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467177 };
7178
7179 MockRead good_cert_reads[] = {
7180 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7181 MockRead("HTTP/1.0 200 OK\r\n"),
7182 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7183 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067184 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467185 };
7186
7187 StaticSocketDataProvider ssl_bad_certificate(
7188 bad_cert_reads, arraysize(bad_cert_reads),
7189 bad_cert_writes, arraysize(bad_cert_writes));
7190 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7191 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067192 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7193 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467194
7195 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077196 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7197 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7198 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467199
7200 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077201 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7202 session_deps_.socket_factory->AddSocketDataProvider(&data);
7203 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467204
[email protected]49639fa2011-12-20 23:22:417205 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467206
[email protected]3fe8d2f82013-10-17 08:56:077207 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467208 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467210
[email protected]49639fa2011-12-20 23:22:417211 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467212 EXPECT_EQ(ERR_IO_PENDING, rv);
7213
7214 rv = callback.WaitForResult();
7215 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7216
[email protected]49639fa2011-12-20 23:22:417217 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467218 EXPECT_EQ(ERR_IO_PENDING, rv);
7219
7220 rv = callback.WaitForResult();
7221 EXPECT_EQ(OK, rv);
7222
7223 const HttpResponseInfo* response = trans->GetResponseInfo();
7224
[email protected]fe2255a2011-09-20 19:37:507225 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467226 EXPECT_EQ(100, response->headers->GetContentLength());
7227}
7228
[email protected]23e482282013-06-14 16:08:027229TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427230 HttpRequestInfo request;
7231 request.method = "GET";
bncce36dca22015-04-21 22:11:237232 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437233 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7234 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427235
[email protected]3fe8d2f82013-10-17 08:56:077236 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277237 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417238 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277239
[email protected]1c773ea12009-04-28 19:58:427240 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237241 MockWrite(
7242 "GET / HTTP/1.1\r\n"
7243 "Host: www.example.org\r\n"
7244 "Connection: keep-alive\r\n"
7245 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427246 };
7247
7248 // Lastly, the server responds with the actual content.
7249 MockRead data_reads[] = {
7250 MockRead("HTTP/1.0 200 OK\r\n"),
7251 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7252 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067253 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427254 };
7255
[email protected]31a2bfe2010-02-09 08:03:397256 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7257 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077258 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427259
[email protected]49639fa2011-12-20 23:22:417260 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427261
[email protected]49639fa2011-12-20 23:22:417262 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427263 EXPECT_EQ(ERR_IO_PENDING, rv);
7264
7265 rv = callback.WaitForResult();
7266 EXPECT_EQ(OK, rv);
7267}
7268
[email protected]23e482282013-06-14 16:08:027269TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297270 HttpRequestInfo request;
7271 request.method = "GET";
bncce36dca22015-04-21 22:11:237272 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297273 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7274 "Chromium Ultra Awesome X Edition");
7275
[email protected]bb88e1d32013-05-03 23:11:077276 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:077277 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277278 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417279 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277280
[email protected]da81f132010-08-18 23:39:297281 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237282 MockWrite(
7283 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7284 "Host: www.example.org\r\n"
7285 "Proxy-Connection: keep-alive\r\n"
7286 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297287 };
7288 MockRead data_reads[] = {
7289 // Return an error, so the transaction stops here (this test isn't
7290 // interested in the rest).
7291 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7292 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7293 MockRead("Proxy-Connection: close\r\n\r\n"),
7294 };
7295
7296 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7297 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077298 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297299
[email protected]49639fa2011-12-20 23:22:417300 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297301
[email protected]49639fa2011-12-20 23:22:417302 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297303 EXPECT_EQ(ERR_IO_PENDING, rv);
7304
7305 rv = callback.WaitForResult();
7306 EXPECT_EQ(OK, rv);
7307}
7308
[email protected]23e482282013-06-14 16:08:027309TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427310 HttpRequestInfo request;
7311 request.method = "GET";
bncce36dca22015-04-21 22:11:237312 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427313 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167314 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7315 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427316
[email protected]3fe8d2f82013-10-17 08:56:077317 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277318 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417319 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277320
[email protected]1c773ea12009-04-28 19:58:427321 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237322 MockWrite(
7323 "GET / HTTP/1.1\r\n"
7324 "Host: www.example.org\r\n"
7325 "Connection: keep-alive\r\n"
7326 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427327 };
7328
7329 // Lastly, the server responds with the actual content.
7330 MockRead data_reads[] = {
7331 MockRead("HTTP/1.0 200 OK\r\n"),
7332 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7333 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067334 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427335 };
7336
[email protected]31a2bfe2010-02-09 08:03:397337 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7338 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077339 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427340
[email protected]49639fa2011-12-20 23:22:417341 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427342
[email protected]49639fa2011-12-20 23:22:417343 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427344 EXPECT_EQ(ERR_IO_PENDING, rv);
7345
7346 rv = callback.WaitForResult();
7347 EXPECT_EQ(OK, rv);
7348}
7349
[email protected]23e482282013-06-14 16:08:027350TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427351 HttpRequestInfo request;
7352 request.method = "POST";
bncce36dca22015-04-21 22:11:237353 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427354
[email protected]3fe8d2f82013-10-17 08:56:077355 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277356 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417357 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277358
[email protected]1c773ea12009-04-28 19:58:427359 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237360 MockWrite(
7361 "POST / HTTP/1.1\r\n"
7362 "Host: www.example.org\r\n"
7363 "Connection: keep-alive\r\n"
7364 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427365 };
7366
7367 // Lastly, the server responds with the actual content.
7368 MockRead data_reads[] = {
7369 MockRead("HTTP/1.0 200 OK\r\n"),
7370 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7371 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067372 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427373 };
7374
[email protected]31a2bfe2010-02-09 08:03:397375 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7376 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077377 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427378
[email protected]49639fa2011-12-20 23:22:417379 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427380
[email protected]49639fa2011-12-20 23:22:417381 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427382 EXPECT_EQ(ERR_IO_PENDING, rv);
7383
7384 rv = callback.WaitForResult();
7385 EXPECT_EQ(OK, rv);
7386}
7387
[email protected]23e482282013-06-14 16:08:027388TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427389 HttpRequestInfo request;
7390 request.method = "PUT";
bncce36dca22015-04-21 22:11:237391 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427392
[email protected]3fe8d2f82013-10-17 08:56:077393 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277394 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417395 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277396
[email protected]1c773ea12009-04-28 19:58:427397 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237398 MockWrite(
7399 "PUT / HTTP/1.1\r\n"
7400 "Host: www.example.org\r\n"
7401 "Connection: keep-alive\r\n"
7402 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427403 };
7404
7405 // Lastly, the server responds with the actual content.
7406 MockRead data_reads[] = {
7407 MockRead("HTTP/1.0 200 OK\r\n"),
7408 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7409 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067410 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427411 };
7412
[email protected]31a2bfe2010-02-09 08:03:397413 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7414 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077415 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427416
[email protected]49639fa2011-12-20 23:22:417417 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427418
[email protected]49639fa2011-12-20 23:22:417419 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427420 EXPECT_EQ(ERR_IO_PENDING, rv);
7421
7422 rv = callback.WaitForResult();
7423 EXPECT_EQ(OK, rv);
7424}
7425
[email protected]23e482282013-06-14 16:08:027426TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427427 HttpRequestInfo request;
7428 request.method = "HEAD";
bncce36dca22015-04-21 22:11:237429 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427430
[email protected]3fe8d2f82013-10-17 08:56:077431 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277432 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417433 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277434
[email protected]1c773ea12009-04-28 19:58:427435 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:137436 MockWrite("HEAD / HTTP/1.1\r\n"
7437 "Host: www.example.org\r\n"
7438 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427439 };
7440
7441 // Lastly, the server responds with the actual content.
7442 MockRead data_reads[] = {
7443 MockRead("HTTP/1.0 200 OK\r\n"),
7444 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7445 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067446 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427447 };
7448
[email protected]31a2bfe2010-02-09 08:03:397449 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7450 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077451 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427452
[email protected]49639fa2011-12-20 23:22:417453 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427454
[email protected]49639fa2011-12-20 23:22:417455 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427456 EXPECT_EQ(ERR_IO_PENDING, rv);
7457
7458 rv = callback.WaitForResult();
7459 EXPECT_EQ(OK, rv);
7460}
7461
[email protected]23e482282013-06-14 16:08:027462TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427463 HttpRequestInfo request;
7464 request.method = "GET";
bncce36dca22015-04-21 22:11:237465 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427466 request.load_flags = LOAD_BYPASS_CACHE;
7467
[email protected]3fe8d2f82013-10-17 08:56:077468 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277469 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417470 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277471
[email protected]1c773ea12009-04-28 19:58:427472 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237473 MockWrite(
7474 "GET / HTTP/1.1\r\n"
7475 "Host: www.example.org\r\n"
7476 "Connection: keep-alive\r\n"
7477 "Pragma: no-cache\r\n"
7478 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427479 };
7480
7481 // Lastly, the server responds with the actual content.
7482 MockRead data_reads[] = {
7483 MockRead("HTTP/1.0 200 OK\r\n"),
7484 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7485 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067486 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427487 };
7488
[email protected]31a2bfe2010-02-09 08:03:397489 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7490 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077491 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427492
[email protected]49639fa2011-12-20 23:22:417493 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427494
[email protected]49639fa2011-12-20 23:22:417495 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427496 EXPECT_EQ(ERR_IO_PENDING, rv);
7497
7498 rv = callback.WaitForResult();
7499 EXPECT_EQ(OK, rv);
7500}
7501
[email protected]23e482282013-06-14 16:08:027502TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427503 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427504 HttpRequestInfo request;
7505 request.method = "GET";
bncce36dca22015-04-21 22:11:237506 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427507 request.load_flags = LOAD_VALIDATE_CACHE;
7508
[email protected]3fe8d2f82013-10-17 08:56:077509 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277510 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417511 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277512
[email protected]1c773ea12009-04-28 19:58:427513 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237514 MockWrite(
7515 "GET / HTTP/1.1\r\n"
7516 "Host: www.example.org\r\n"
7517 "Connection: keep-alive\r\n"
7518 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427519 };
7520
7521 // Lastly, the server responds with the actual content.
7522 MockRead data_reads[] = {
7523 MockRead("HTTP/1.0 200 OK\r\n"),
7524 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7525 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067526 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427527 };
7528
[email protected]31a2bfe2010-02-09 08:03:397529 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7530 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077531 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427532
[email protected]49639fa2011-12-20 23:22:417533 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427534
[email protected]49639fa2011-12-20 23:22:417535 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427536 EXPECT_EQ(ERR_IO_PENDING, rv);
7537
7538 rv = callback.WaitForResult();
7539 EXPECT_EQ(OK, rv);
7540}
7541
[email protected]23e482282013-06-14 16:08:027542TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427543 HttpRequestInfo request;
7544 request.method = "GET";
bncce36dca22015-04-21 22:11:237545 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437546 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427547
[email protected]3fe8d2f82013-10-17 08:56:077548 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277549 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417550 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277551
[email protected]1c773ea12009-04-28 19:58:427552 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237553 MockWrite(
7554 "GET / HTTP/1.1\r\n"
7555 "Host: www.example.org\r\n"
7556 "Connection: keep-alive\r\n"
7557 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427558 };
7559
7560 // Lastly, the server responds with the actual content.
7561 MockRead data_reads[] = {
7562 MockRead("HTTP/1.0 200 OK\r\n"),
7563 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7564 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067565 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427566 };
7567
[email protected]31a2bfe2010-02-09 08:03:397568 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7569 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077570 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427571
[email protected]49639fa2011-12-20 23:22:417572 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427573
[email protected]49639fa2011-12-20 23:22:417574 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427575 EXPECT_EQ(ERR_IO_PENDING, rv);
7576
7577 rv = callback.WaitForResult();
7578 EXPECT_EQ(OK, rv);
7579}
7580
[email protected]23e482282013-06-14 16:08:027581TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477582 HttpRequestInfo request;
7583 request.method = "GET";
bncce36dca22015-04-21 22:11:237584 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437585 request.extra_headers.SetHeader("referer", "www.foo.com");
7586 request.extra_headers.SetHeader("hEllo", "Kitty");
7587 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477588
[email protected]3fe8d2f82013-10-17 08:56:077589 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277590 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417591 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277592
[email protected]270c6412010-03-29 22:02:477593 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237594 MockWrite(
7595 "GET / HTTP/1.1\r\n"
7596 "Host: www.example.org\r\n"
7597 "Connection: keep-alive\r\n"
7598 "referer: www.foo.com\r\n"
7599 "hEllo: Kitty\r\n"
7600 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:477601 };
7602
7603 // Lastly, the server responds with the actual content.
7604 MockRead data_reads[] = {
7605 MockRead("HTTP/1.0 200 OK\r\n"),
7606 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7607 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067608 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477609 };
7610
7611 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7612 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077613 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477614
[email protected]49639fa2011-12-20 23:22:417615 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477616
[email protected]49639fa2011-12-20 23:22:417617 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477618 EXPECT_EQ(ERR_IO_PENDING, rv);
7619
7620 rv = callback.WaitForResult();
7621 EXPECT_EQ(OK, rv);
7622}
7623
[email protected]23e482282013-06-14 16:08:027624TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277625 HttpRequestInfo request;
7626 request.method = "GET";
bncce36dca22015-04-21 22:11:237627 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277628 request.load_flags = 0;
7629
[email protected]bb88e1d32013-05-03 23:11:077630 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207631 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517632 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077633 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027634
[email protected]3fe8d2f82013-10-17 08:56:077635 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027636 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417637 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027638
[email protected]3cd17242009-06-23 02:59:027639 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7640 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7641
7642 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237643 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7644 MockWrite(
7645 "GET / HTTP/1.1\r\n"
7646 "Host: www.example.org\r\n"
7647 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027648
7649 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067650 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027651 MockRead("HTTP/1.0 200 OK\r\n"),
7652 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7653 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067654 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027655 };
7656
[email protected]31a2bfe2010-02-09 08:03:397657 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7658 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077659 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027660
[email protected]49639fa2011-12-20 23:22:417661 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027662
[email protected]49639fa2011-12-20 23:22:417663 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027664 EXPECT_EQ(ERR_IO_PENDING, rv);
7665
7666 rv = callback.WaitForResult();
7667 EXPECT_EQ(OK, rv);
7668
7669 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507670 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027671
[email protected]029c83b62013-01-24 05:28:207672 LoadTimingInfo load_timing_info;
7673 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7674 TestLoadTimingNotReusedWithPac(load_timing_info,
7675 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7676
[email protected]3cd17242009-06-23 02:59:027677 std::string response_text;
7678 rv = ReadTransaction(trans.get(), &response_text);
7679 EXPECT_EQ(OK, rv);
7680 EXPECT_EQ("Payload", response_text);
7681}
7682
[email protected]23e482282013-06-14 16:08:027683TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277684 HttpRequestInfo request;
7685 request.method = "GET";
bncce36dca22015-04-21 22:11:237686 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277687 request.load_flags = 0;
7688
[email protected]bb88e1d32013-05-03 23:11:077689 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207690 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517691 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077692 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027693
[email protected]3fe8d2f82013-10-17 08:56:077694 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027695 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417696 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027697
[email protected]3cd17242009-06-23 02:59:027698 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7699 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7700
7701 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237702 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7703 arraysize(write_buffer)),
7704 MockWrite(
7705 "GET / HTTP/1.1\r\n"
7706 "Host: www.example.org\r\n"
7707 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027708
7709 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017710 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7711 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357712 MockRead("HTTP/1.0 200 OK\r\n"),
7713 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7714 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067715 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357716 };
7717
[email protected]31a2bfe2010-02-09 08:03:397718 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7719 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077720 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357721
[email protected]8ddf8322012-02-23 18:08:067722 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357724
[email protected]49639fa2011-12-20 23:22:417725 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357726
[email protected]49639fa2011-12-20 23:22:417727 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357728 EXPECT_EQ(ERR_IO_PENDING, rv);
7729
7730 rv = callback.WaitForResult();
7731 EXPECT_EQ(OK, rv);
7732
[email protected]029c83b62013-01-24 05:28:207733 LoadTimingInfo load_timing_info;
7734 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7735 TestLoadTimingNotReusedWithPac(load_timing_info,
7736 CONNECT_TIMING_HAS_SSL_TIMES);
7737
[email protected]e0c27be2009-07-15 13:09:357738 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507739 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357740
7741 std::string response_text;
7742 rv = ReadTransaction(trans.get(), &response_text);
7743 EXPECT_EQ(OK, rv);
7744 EXPECT_EQ("Payload", response_text);
7745}
7746
[email protected]23e482282013-06-14 16:08:027747TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207748 HttpRequestInfo request;
7749 request.method = "GET";
bncce36dca22015-04-21 22:11:237750 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:207751 request.load_flags = 0;
7752
[email protected]bb88e1d32013-05-03 23:11:077753 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207754 ProxyService::CreateFixed("socks4://myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517755 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077756 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207757
[email protected]3fe8d2f82013-10-17 08:56:077758 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207759 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417760 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207761
7762 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7763 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7764
7765 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237766 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7767 MockWrite(
7768 "GET / HTTP/1.1\r\n"
7769 "Host: www.example.org\r\n"
7770 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:207771
7772 MockRead data_reads[] = {
7773 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7774 MockRead("HTTP/1.0 200 OK\r\n"),
7775 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7776 MockRead("Payload"),
7777 MockRead(SYNCHRONOUS, OK)
7778 };
7779
7780 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7781 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077782 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207783
7784 TestCompletionCallback callback;
7785
7786 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7787 EXPECT_EQ(ERR_IO_PENDING, rv);
7788
7789 rv = callback.WaitForResult();
7790 EXPECT_EQ(OK, rv);
7791
7792 const HttpResponseInfo* response = trans->GetResponseInfo();
7793 ASSERT_TRUE(response != NULL);
7794
7795 LoadTimingInfo load_timing_info;
7796 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7797 TestLoadTimingNotReused(load_timing_info,
7798 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7799
7800 std::string response_text;
7801 rv = ReadTransaction(trans.get(), &response_text);
7802 EXPECT_EQ(OK, rv);
7803 EXPECT_EQ("Payload", response_text);
7804}
7805
[email protected]23e482282013-06-14 16:08:027806TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277807 HttpRequestInfo request;
7808 request.method = "GET";
bncce36dca22015-04-21 22:11:237809 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277810 request.load_flags = 0;
7811
[email protected]bb88e1d32013-05-03 23:11:077812 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207813 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517814 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077815 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357816
[email protected]3fe8d2f82013-10-17 08:56:077817 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357818 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417819 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357820
[email protected]e0c27be2009-07-15 13:09:357821 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7822 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377823 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237824 0x05, // Version
7825 0x01, // Command (CONNECT)
7826 0x00, // Reserved.
7827 0x03, // Address type (DOMAINNAME).
7828 0x0F, // Length of domain (15)
7829 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7830 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:377831 };
[email protected]e0c27be2009-07-15 13:09:357832 const char kSOCKS5OkResponse[] =
7833 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7834
7835 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237836 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7837 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7838 MockWrite(
7839 "GET / HTTP/1.1\r\n"
7840 "Host: www.example.org\r\n"
7841 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357842
7843 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017844 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7845 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357846 MockRead("HTTP/1.0 200 OK\r\n"),
7847 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7848 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067849 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357850 };
7851
[email protected]31a2bfe2010-02-09 08:03:397852 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7853 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077854 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357855
[email protected]49639fa2011-12-20 23:22:417856 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357857
[email protected]49639fa2011-12-20 23:22:417858 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357859 EXPECT_EQ(ERR_IO_PENDING, rv);
7860
7861 rv = callback.WaitForResult();
7862 EXPECT_EQ(OK, rv);
7863
7864 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507865 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357866
[email protected]029c83b62013-01-24 05:28:207867 LoadTimingInfo load_timing_info;
7868 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7869 TestLoadTimingNotReusedWithPac(load_timing_info,
7870 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7871
[email protected]e0c27be2009-07-15 13:09:357872 std::string response_text;
7873 rv = ReadTransaction(trans.get(), &response_text);
7874 EXPECT_EQ(OK, rv);
7875 EXPECT_EQ("Payload", response_text);
7876}
7877
[email protected]23e482282013-06-14 16:08:027878TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277879 HttpRequestInfo request;
7880 request.method = "GET";
bncce36dca22015-04-21 22:11:237881 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277882 request.load_flags = 0;
7883
[email protected]bb88e1d32013-05-03 23:11:077884 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207885 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517886 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077887 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357888
[email protected]3fe8d2f82013-10-17 08:56:077889 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357890 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417891 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357892
[email protected]e0c27be2009-07-15 13:09:357893 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7894 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377895 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237896 0x05, // Version
7897 0x01, // Command (CONNECT)
7898 0x00, // Reserved.
7899 0x03, // Address type (DOMAINNAME).
7900 0x0F, // Length of domain (15)
7901 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7902 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:377903 };
7904
[email protected]e0c27be2009-07-15 13:09:357905 const char kSOCKS5OkResponse[] =
7906 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7907
7908 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237909 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7910 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7911 arraysize(kSOCKS5OkRequest)),
7912 MockWrite(
7913 "GET / HTTP/1.1\r\n"
7914 "Host: www.example.org\r\n"
7915 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357916
7917 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017918 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7919 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027920 MockRead("HTTP/1.0 200 OK\r\n"),
7921 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7922 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067923 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027924 };
7925
[email protected]31a2bfe2010-02-09 08:03:397926 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7927 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077928 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027929
[email protected]8ddf8322012-02-23 18:08:067930 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077931 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027932
[email protected]49639fa2011-12-20 23:22:417933 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027934
[email protected]49639fa2011-12-20 23:22:417935 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027936 EXPECT_EQ(ERR_IO_PENDING, rv);
7937
7938 rv = callback.WaitForResult();
7939 EXPECT_EQ(OK, rv);
7940
7941 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507942 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027943
[email protected]029c83b62013-01-24 05:28:207944 LoadTimingInfo load_timing_info;
7945 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7946 TestLoadTimingNotReusedWithPac(load_timing_info,
7947 CONNECT_TIMING_HAS_SSL_TIMES);
7948
[email protected]3cd17242009-06-23 02:59:027949 std::string response_text;
7950 rv = ReadTransaction(trans.get(), &response_text);
7951 EXPECT_EQ(OK, rv);
7952 EXPECT_EQ("Payload", response_text);
7953}
7954
[email protected]448d4ca52012-03-04 04:12:237955namespace {
7956
[email protected]04e5be32009-06-26 20:00:317957// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067958
7959struct GroupNameTest {
7960 std::string proxy_server;
7961 std::string url;
7962 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187963 bool ssl;
[email protected]2d731a32010-04-29 01:04:067964};
7965
7966scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437967 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077968 SpdySessionDependencies* session_deps_) {
7969 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067970
[email protected]30d4c022013-07-18 22:58:167971 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537972 session->http_server_properties();
bnccacc0992015-03-20 20:22:227973 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:257974 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:127975 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:227976 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:127977 HostPortPair("host.with.alternate", 80), alternative_service, 1.0,
7978 expiration);
[email protected]2d731a32010-04-29 01:04:067979
7980 return session;
7981}
7982
7983int GroupNameTransactionHelper(
7984 const std::string& url,
7985 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067986 HttpRequestInfo request;
7987 request.method = "GET";
7988 request.url = GURL(url);
7989 request.load_flags = 0;
7990
[email protected]262eec82013-03-19 21:01:367991 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507992 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277993
[email protected]49639fa2011-12-20 23:22:417994 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067995
7996 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417997 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067998}
7999
[email protected]448d4ca52012-03-04 04:12:238000} // namespace
8001
[email protected]23e482282013-06-14 16:08:028002TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:068003 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238004 {
8005 "", // unused
8006 "http://www.example.org/direct",
8007 "www.example.org:80",
8008 false,
8009 },
8010 {
8011 "", // unused
8012 "http://[2001:1418:13:1::25]/direct",
8013 "[2001:1418:13:1::25]:80",
8014 false,
8015 },
[email protected]04e5be32009-06-26 20:00:318016
bncce36dca22015-04-21 22:11:238017 // SSL Tests
8018 {
8019 "", // unused
8020 "https://www.example.org/direct_ssl",
8021 "ssl/www.example.org:443",
8022 true,
8023 },
8024 {
8025 "", // unused
8026 "https://[2001:1418:13:1::25]/direct",
8027 "ssl/[2001:1418:13:1::25]:443",
8028 true,
8029 },
8030 {
8031 "", // unused
8032 "http://host.with.alternate/direct",
8033 "ssl/host.with.alternate:443",
8034 true,
8035 },
[email protected]2d731a32010-04-29 01:04:068036 };
[email protected]2ff8b312010-04-26 22:20:548037
bnc55ff9da2015-08-19 18:42:358038 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068039
viettrungluue4a8b882014-10-16 06:17:388040 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078041 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028042 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068043 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438044 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068045
8046 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:288047 CaptureGroupNameTransportSocketPool* transport_conn_pool =
8048 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138049 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348050 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:448051 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8052 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028053 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
8054 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518055 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068056
8057 EXPECT_EQ(ERR_IO_PENDING,
8058 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188059 if (tests[i].ssl)
8060 EXPECT_EQ(tests[i].expected_group_name,
8061 ssl_conn_pool->last_group_name_received());
8062 else
8063 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:288064 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068065 }
[email protected]2d731a32010-04-29 01:04:068066}
8067
[email protected]23e482282013-06-14 16:08:028068TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:068069 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238070 {
8071 "http_proxy",
8072 "http://www.example.org/http_proxy_normal",
8073 "www.example.org:80",
8074 false,
8075 },
[email protected]2d731a32010-04-29 01:04:068076
bncce36dca22015-04-21 22:11:238077 // SSL Tests
8078 {
8079 "http_proxy",
8080 "https://www.example.org/http_connect_ssl",
8081 "ssl/www.example.org:443",
8082 true,
8083 },
[email protected]af3490e2010-10-16 21:02:298084
bncce36dca22015-04-21 22:11:238085 {
8086 "http_proxy",
8087 "http://host.with.alternate/direct",
8088 "ssl/host.with.alternate:443",
8089 true,
8090 },
[email protected]45499252013-01-23 17:12:568091
bncce36dca22015-04-21 22:11:238092 {
8093 "http_proxy",
8094 "ftp://ftp.google.com/http_proxy_normal",
8095 "ftp/ftp.google.com:21",
8096 false,
8097 },
[email protected]2d731a32010-04-29 01:04:068098 };
8099
bnc55ff9da2015-08-19 18:42:358100 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068101
viettrungluue4a8b882014-10-16 06:17:388102 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078103 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028104 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068105 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438106 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068107
8108 HttpNetworkSessionPeer peer(session);
8109
[email protected]e60e47a2010-07-14 03:37:188110 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138111 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348112 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138113 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348114 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028115
[email protected]831e4a32013-11-14 02:14:448116 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8117 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028118 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8119 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518120 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068121
8122 EXPECT_EQ(ERR_IO_PENDING,
8123 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188124 if (tests[i].ssl)
8125 EXPECT_EQ(tests[i].expected_group_name,
8126 ssl_conn_pool->last_group_name_received());
8127 else
8128 EXPECT_EQ(tests[i].expected_group_name,
8129 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068130 }
[email protected]2d731a32010-04-29 01:04:068131}
8132
[email protected]23e482282013-06-14 16:08:028133TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068134 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238135 {
8136 "socks4://socks_proxy:1080",
8137 "http://www.example.org/socks4_direct",
8138 "socks4/www.example.org:80",
8139 false,
8140 },
8141 {
8142 "socks5://socks_proxy:1080",
8143 "http://www.example.org/socks5_direct",
8144 "socks5/www.example.org:80",
8145 false,
8146 },
[email protected]2d731a32010-04-29 01:04:068147
bncce36dca22015-04-21 22:11:238148 // SSL Tests
8149 {
8150 "socks4://socks_proxy:1080",
8151 "https://www.example.org/socks4_ssl",
8152 "socks4/ssl/www.example.org:443",
8153 true,
8154 },
8155 {
8156 "socks5://socks_proxy:1080",
8157 "https://www.example.org/socks5_ssl",
8158 "socks5/ssl/www.example.org:443",
8159 true,
8160 },
[email protected]af3490e2010-10-16 21:02:298161
bncce36dca22015-04-21 22:11:238162 {
8163 "socks4://socks_proxy:1080",
8164 "http://host.with.alternate/direct",
8165 "socks4/ssl/host.with.alternate:443",
8166 true,
8167 },
[email protected]04e5be32009-06-26 20:00:318168 };
8169
bnc55ff9da2015-08-19 18:42:358170 session_deps_.use_alternative_services = true;
[email protected]2ff8b312010-04-26 22:20:548171
viettrungluue4a8b882014-10-16 06:17:388172 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078173 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028174 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068175 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438176 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028177
[email protected]2d731a32010-04-29 01:04:068178 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318179
[email protected]e60e47a2010-07-14 03:37:188180 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138181 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348182 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138183 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348184 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028185
[email protected]831e4a32013-11-14 02:14:448186 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8187 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028188 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8189 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518190 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318191
[email protected]262eec82013-03-19 21:01:368192 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508193 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318194
[email protected]2d731a32010-04-29 01:04:068195 EXPECT_EQ(ERR_IO_PENDING,
8196 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188197 if (tests[i].ssl)
8198 EXPECT_EQ(tests[i].expected_group_name,
8199 ssl_conn_pool->last_group_name_received());
8200 else
8201 EXPECT_EQ(tests[i].expected_group_name,
8202 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318203 }
8204}
8205
[email protected]23e482282013-06-14 16:08:028206TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278207 HttpRequestInfo request;
8208 request.method = "GET";
bncce36dca22015-04-21 22:11:238209 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278210
[email protected]bb88e1d32013-05-03 23:11:078211 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008212 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328213
[email protected]69719062010-01-05 20:09:218214 // This simulates failure resolving all hostnames; that means we will fail
8215 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078216 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328217
[email protected]3fe8d2f82013-10-17 08:56:078218 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258219 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418220 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258221
[email protected]49639fa2011-12-20 23:22:418222 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258223
[email protected]49639fa2011-12-20 23:22:418224 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258225 EXPECT_EQ(ERR_IO_PENDING, rv);
8226
[email protected]9172a982009-06-06 00:30:258227 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018228 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258229}
8230
[email protected]685af592010-05-11 19:31:248231// Base test to make sure that when the load flags for a request specify to
8232// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028233void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078234 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278235 // Issue a request, asking to bypass the cache(s).
8236 HttpRequestInfo request;
8237 request.method = "GET";
8238 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238239 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278240
[email protected]a2c2fb92009-07-18 07:31:048241 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078242 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328243
[email protected]3fe8d2f82013-10-17 08:56:078244 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8245 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418246 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288247
bncce36dca22015-04-21 22:11:238248 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288249 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298250 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078251 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238252 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8253 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478254 EXPECT_EQ(ERR_IO_PENDING, rv);
8255 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288256 EXPECT_EQ(OK, rv);
8257
8258 // Verify that it was added to host cache, by doing a subsequent async lookup
8259 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078260 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238261 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8262 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328263 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288264
bncce36dca22015-04-21 22:11:238265 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288266 // we can tell if the next lookup hit the cache, or the "network".
8267 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238268 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288269
8270 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8271 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068272 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398273 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078274 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288275
[email protected]3b9cca42009-06-16 01:08:288276 // Run the request.
[email protected]49639fa2011-12-20 23:22:418277 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288278 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418279 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288280
8281 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238282 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288283 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8284}
8285
[email protected]685af592010-05-11 19:31:248286// There are multiple load flags that should trigger the host cache bypass.
8287// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028288TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248289 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8290}
8291
[email protected]23e482282013-06-14 16:08:028292TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248293 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8294}
8295
[email protected]23e482282013-06-14 16:08:028296TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248297 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8298}
8299
[email protected]0877e3d2009-10-17 22:29:578300// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028301TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578302 HttpRequestInfo request;
8303 request.method = "GET";
8304 request.url = GURL("http://www.foo.com/");
8305 request.load_flags = 0;
8306
8307 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068308 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578309 };
[email protected]31a2bfe2010-02-09 08:03:398310 StaticSocketDataProvider data(NULL, 0,
8311 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078312 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078313 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578314
[email protected]49639fa2011-12-20 23:22:418315 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578316
8317 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418318 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578319
[email protected]49639fa2011-12-20 23:22:418320 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578321 EXPECT_EQ(ERR_IO_PENDING, rv);
8322
8323 rv = callback.WaitForResult();
8324 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8325}
8326
zmo9528c9f42015-08-04 22:12:088327// Check that a connection closed after the start of the headers finishes ok.
8328TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578329 HttpRequestInfo request;
8330 request.method = "GET";
8331 request.url = GURL("http://www.foo.com/");
8332 request.load_flags = 0;
8333
8334 MockRead data_reads[] = {
8335 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068336 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578337 };
8338
[email protected]31a2bfe2010-02-09 08:03:398339 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078340 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078341 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578342
[email protected]49639fa2011-12-20 23:22:418343 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578344
8345 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418346 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578347
[email protected]49639fa2011-12-20 23:22:418348 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578349 EXPECT_EQ(ERR_IO_PENDING, rv);
8350
8351 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:088352 EXPECT_EQ(OK, rv);
8353
8354 const HttpResponseInfo* response = trans->GetResponseInfo();
8355 ASSERT_TRUE(response != NULL);
8356
8357 EXPECT_TRUE(response->headers.get() != NULL);
8358 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8359
8360 std::string response_data;
8361 rv = ReadTransaction(trans.get(), &response_data);
8362 EXPECT_EQ(OK, rv);
8363 EXPECT_EQ("", response_data);
[email protected]0877e3d2009-10-17 22:29:578364}
8365
8366// Make sure that a dropped connection while draining the body for auth
8367// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028368TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578369 HttpRequestInfo request;
8370 request.method = "GET";
bncce36dca22015-04-21 22:11:238371 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578372 request.load_flags = 0;
8373
8374 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238375 MockWrite(
8376 "GET / HTTP/1.1\r\n"
8377 "Host: www.example.org\r\n"
8378 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578379 };
8380
8381 MockRead data_reads1[] = {
8382 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8383 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8384 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8385 MockRead("Content-Length: 14\r\n\r\n"),
8386 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068387 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578388 };
8389
[email protected]31a2bfe2010-02-09 08:03:398390 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8391 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078392 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578393
8394 // After calling trans->RestartWithAuth(), this is the request we should
8395 // be issuing -- the final header line contains the credentials.
8396 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238397 MockWrite(
8398 "GET / HTTP/1.1\r\n"
8399 "Host: www.example.org\r\n"
8400 "Connection: keep-alive\r\n"
8401 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578402 };
8403
8404 // Lastly, the server responds with the actual content.
8405 MockRead data_reads2[] = {
8406 MockRead("HTTP/1.1 200 OK\r\n"),
8407 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8408 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068409 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578410 };
8411
[email protected]31a2bfe2010-02-09 08:03:398412 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8413 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078414 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:078415 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578416
[email protected]49639fa2011-12-20 23:22:418417 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578418
[email protected]262eec82013-03-19 21:01:368419 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508420 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508421
[email protected]49639fa2011-12-20 23:22:418422 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578423 EXPECT_EQ(ERR_IO_PENDING, rv);
8424
8425 rv = callback1.WaitForResult();
8426 EXPECT_EQ(OK, rv);
8427
8428 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508429 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048430 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578431
[email protected]49639fa2011-12-20 23:22:418432 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578433
[email protected]49639fa2011-12-20 23:22:418434 rv = trans->RestartWithAuth(
8435 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578436 EXPECT_EQ(ERR_IO_PENDING, rv);
8437
8438 rv = callback2.WaitForResult();
8439 EXPECT_EQ(OK, rv);
8440
8441 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508442 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578443 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8444 EXPECT_EQ(100, response->headers->GetContentLength());
8445}
8446
8447// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028448TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078449 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578450
8451 HttpRequestInfo request;
8452 request.method = "GET";
bncce36dca22015-04-21 22:11:238453 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578454 request.load_flags = 0;
8455
8456 MockRead proxy_reads[] = {
8457 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068458 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578459 };
8460
[email protected]31a2bfe2010-02-09 08:03:398461 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068462 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578463
[email protected]bb88e1d32013-05-03 23:11:078464 session_deps_.socket_factory->AddSocketDataProvider(&data);
8465 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578466
[email protected]49639fa2011-12-20 23:22:418467 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578468
[email protected]bb88e1d32013-05-03 23:11:078469 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578470
[email protected]3fe8d2f82013-10-17 08:56:078471 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578472 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418473 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578474
[email protected]49639fa2011-12-20 23:22:418475 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578476 EXPECT_EQ(ERR_IO_PENDING, rv);
8477
8478 rv = callback.WaitForResult();
8479 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8480}
8481
[email protected]23e482282013-06-14 16:08:028482TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468483 HttpRequestInfo request;
8484 request.method = "GET";
bncce36dca22015-04-21 22:11:238485 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468486 request.load_flags = 0;
8487
[email protected]3fe8d2f82013-10-17 08:56:078488 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278489 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418490 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278491
[email protected]e22e1362009-11-23 21:31:128492 MockRead data_reads[] = {
8493 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068494 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128495 };
[email protected]9492e4a2010-02-24 00:58:468496
8497 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078498 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468499
[email protected]49639fa2011-12-20 23:22:418500 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468501
[email protected]49639fa2011-12-20 23:22:418502 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468503 EXPECT_EQ(ERR_IO_PENDING, rv);
8504
8505 EXPECT_EQ(OK, callback.WaitForResult());
8506
8507 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508508 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468509
[email protected]90499482013-06-01 00:39:508510 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468511 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8512
8513 std::string response_data;
8514 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238515 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128516}
8517
[email protected]23e482282013-06-14 16:08:028518TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158519 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528520 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338521 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218522 UploadFileElementReader::ScopedOverridingContentLengthForTests
8523 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338524
[email protected]b2d26cfd2012-12-11 10:36:068525 ScopedVector<UploadElementReader> element_readers;
8526 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458527 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8528 temp_file_path, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078529 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278530
8531 HttpRequestInfo request;
8532 request.method = "POST";
bncce36dca22015-04-21 22:11:238533 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278534 request.upload_data_stream = &upload_data_stream;
8535 request.load_flags = 0;
8536
[email protected]3fe8d2f82013-10-17 08:56:078537 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278538 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338540
8541 MockRead data_reads[] = {
8542 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8543 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068544 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338545 };
[email protected]31a2bfe2010-02-09 08:03:398546 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078547 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338548
[email protected]49639fa2011-12-20 23:22:418549 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338550
[email protected]49639fa2011-12-20 23:22:418551 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338552 EXPECT_EQ(ERR_IO_PENDING, rv);
8553
8554 rv = callback.WaitForResult();
8555 EXPECT_EQ(OK, rv);
8556
8557 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508558 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338559
[email protected]90499482013-06-01 00:39:508560 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338561 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8562
8563 std::string response_data;
8564 rv = ReadTransaction(trans.get(), &response_data);
8565 EXPECT_EQ(OK, rv);
8566 EXPECT_EQ("hello world", response_data);
8567
[email protected]dd3aa792013-07-16 19:10:238568 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338569}
8570
[email protected]23e482282013-06-14 16:08:028571TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158572 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528573 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368574 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308575 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368576 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118577 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368578
[email protected]b2d26cfd2012-12-11 10:36:068579 ScopedVector<UploadElementReader> element_readers;
8580 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458581 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8582 temp_file, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078583 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278584
8585 HttpRequestInfo request;
8586 request.method = "POST";
bncce36dca22015-04-21 22:11:238587 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278588 request.upload_data_stream = &upload_data_stream;
8589 request.load_flags = 0;
8590
[email protected]999dd8c2013-11-12 06:45:548591 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078592 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278593 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418594 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368595
[email protected]999dd8c2013-11-12 06:45:548596 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078597 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368598
[email protected]49639fa2011-12-20 23:22:418599 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368600
[email protected]49639fa2011-12-20 23:22:418601 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368602 EXPECT_EQ(ERR_IO_PENDING, rv);
8603
8604 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548605 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368606
[email protected]dd3aa792013-07-16 19:10:238607 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368608}
8609
[email protected]02cad5d2013-10-02 08:14:038610TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8611 class FakeUploadElementReader : public UploadElementReader {
8612 public:
8613 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208614 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038615
8616 const CompletionCallback& callback() const { return callback_; }
8617
8618 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208619 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038620 callback_ = callback;
8621 return ERR_IO_PENDING;
8622 }
dchengb03027d2014-10-21 12:00:208623 uint64 GetContentLength() const override { return 0; }
8624 uint64 BytesRemaining() const override { return 0; }
8625 int Read(IOBuffer* buf,
8626 int buf_length,
8627 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038628 return ERR_FAILED;
8629 }
8630
8631 private:
8632 CompletionCallback callback_;
8633 };
8634
8635 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8636 ScopedVector<UploadElementReader> element_readers;
8637 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078638 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038639
8640 HttpRequestInfo request;
8641 request.method = "POST";
bncce36dca22015-04-21 22:11:238642 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038643 request.upload_data_stream = &upload_data_stream;
8644 request.load_flags = 0;
8645
[email protected]3fe8d2f82013-10-17 08:56:078646 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038647 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418648 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038649
8650 StaticSocketDataProvider data;
8651 session_deps_.socket_factory->AddSocketDataProvider(&data);
8652
8653 TestCompletionCallback callback;
8654 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8655 EXPECT_EQ(ERR_IO_PENDING, rv);
8656 base::MessageLoop::current()->RunUntilIdle();
8657
8658 // Transaction is pending on request body initialization.
8659 ASSERT_FALSE(fake_reader->callback().is_null());
8660
8661 // Return Init()'s result after the transaction gets destroyed.
8662 trans.reset();
8663 fake_reader->callback().Run(OK); // Should not crash.
8664}
8665
[email protected]aeefc9e82010-02-19 16:18:278666// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028667TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278668 HttpRequestInfo request;
8669 request.method = "GET";
bncce36dca22015-04-21 22:11:238670 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278671 request.load_flags = 0;
8672
8673 // First transaction will request a resource and receive a Basic challenge
8674 // with realm="first_realm".
8675 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238676 MockWrite(
8677 "GET / HTTP/1.1\r\n"
8678 "Host: www.example.org\r\n"
8679 "Connection: keep-alive\r\n"
8680 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278681 };
8682 MockRead data_reads1[] = {
8683 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8684 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8685 "\r\n"),
8686 };
8687
8688 // After calling trans->RestartWithAuth(), provide an Authentication header
8689 // for first_realm. The server will reject and provide a challenge with
8690 // second_realm.
8691 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238692 MockWrite(
8693 "GET / HTTP/1.1\r\n"
8694 "Host: www.example.org\r\n"
8695 "Connection: keep-alive\r\n"
8696 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8697 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278698 };
8699 MockRead data_reads2[] = {
8700 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8701 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8702 "\r\n"),
8703 };
8704
8705 // This again fails, and goes back to first_realm. Make sure that the
8706 // entry is removed from cache.
8707 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238708 MockWrite(
8709 "GET / HTTP/1.1\r\n"
8710 "Host: www.example.org\r\n"
8711 "Connection: keep-alive\r\n"
8712 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8713 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278714 };
8715 MockRead data_reads3[] = {
8716 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8717 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8718 "\r\n"),
8719 };
8720
8721 // Try one last time (with the correct password) and get the resource.
8722 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238723 MockWrite(
8724 "GET / HTTP/1.1\r\n"
8725 "Host: www.example.org\r\n"
8726 "Connection: keep-alive\r\n"
8727 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8728 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278729 };
8730 MockRead data_reads4[] = {
8731 MockRead("HTTP/1.1 200 OK\r\n"
8732 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508733 "Content-Length: 5\r\n"
8734 "\r\n"
8735 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278736 };
8737
8738 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8739 data_writes1, arraysize(data_writes1));
8740 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8741 data_writes2, arraysize(data_writes2));
8742 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8743 data_writes3, arraysize(data_writes3));
8744 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8745 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078746 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8747 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8748 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8749 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278750
[email protected]49639fa2011-12-20 23:22:418751 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278752
[email protected]3fe8d2f82013-10-17 08:56:078753 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508754 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418755 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508756
[email protected]aeefc9e82010-02-19 16:18:278757 // Issue the first request with Authorize headers. There should be a
8758 // password prompt for first_realm waiting to be filled in after the
8759 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418760 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278761 EXPECT_EQ(ERR_IO_PENDING, rv);
8762 rv = callback1.WaitForResult();
8763 EXPECT_EQ(OK, rv);
8764 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508765 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048766 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8767 ASSERT_FALSE(challenge == NULL);
8768 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238769 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048770 EXPECT_EQ("first_realm", challenge->realm);
8771 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278772
8773 // Issue the second request with an incorrect password. There should be a
8774 // password prompt for second_realm waiting to be filled in after the
8775 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418776 TestCompletionCallback callback2;
8777 rv = trans->RestartWithAuth(
8778 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278779 EXPECT_EQ(ERR_IO_PENDING, rv);
8780 rv = callback2.WaitForResult();
8781 EXPECT_EQ(OK, rv);
8782 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508783 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048784 challenge = response->auth_challenge.get();
8785 ASSERT_FALSE(challenge == NULL);
8786 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238787 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048788 EXPECT_EQ("second_realm", challenge->realm);
8789 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278790
8791 // Issue the third request with another incorrect password. There should be
8792 // a password prompt for first_realm waiting to be filled in. If the password
8793 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8794 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418795 TestCompletionCallback callback3;
8796 rv = trans->RestartWithAuth(
8797 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278798 EXPECT_EQ(ERR_IO_PENDING, rv);
8799 rv = callback3.WaitForResult();
8800 EXPECT_EQ(OK, rv);
8801 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508802 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048803 challenge = response->auth_challenge.get();
8804 ASSERT_FALSE(challenge == NULL);
8805 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238806 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048807 EXPECT_EQ("first_realm", challenge->realm);
8808 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278809
8810 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418811 TestCompletionCallback callback4;
8812 rv = trans->RestartWithAuth(
8813 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278814 EXPECT_EQ(ERR_IO_PENDING, rv);
8815 rv = callback4.WaitForResult();
8816 EXPECT_EQ(OK, rv);
8817 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508818 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278819 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8820}
8821
bncc958faa2015-07-31 18:14:528822TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
8823 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:358824 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:528825
8826 std::string alternative_service_http_header =
8827 GetAlternativeServiceHttpHeader();
8828
8829 MockRead data_reads[] = {
8830 MockRead("HTTP/1.1 200 OK\r\n"),
8831 MockRead(alternative_service_http_header.c_str()),
8832 MockRead("\r\n"),
8833 MockRead("hello world"),
8834 MockRead(SYNCHRONOUS, OK),
8835 };
8836
8837 HttpRequestInfo request;
8838 request.method = "GET";
8839 request.url = GURL("http://www.example.org/");
8840 request.load_flags = 0;
8841
8842 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8843
8844 session_deps_.socket_factory->AddSocketDataProvider(&data);
8845
8846 TestCompletionCallback callback;
8847
8848 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8849 scoped_ptr<HttpTransaction> trans(
8850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8851
8852 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8853 EXPECT_EQ(ERR_IO_PENDING, rv);
8854
8855 HostPortPair http_host_port_pair("www.example.org", 80);
8856 HttpServerProperties& http_server_properties =
8857 *session->http_server_properties();
8858 AlternativeServiceVector alternative_service_vector =
8859 http_server_properties.GetAlternativeServices(http_host_port_pair);
8860 EXPECT_TRUE(alternative_service_vector.empty());
8861
8862 EXPECT_EQ(OK, callback.WaitForResult());
8863
8864 const HttpResponseInfo* response = trans->GetResponseInfo();
8865 ASSERT_TRUE(response != NULL);
8866 ASSERT_TRUE(response->headers.get() != NULL);
8867 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8868 EXPECT_FALSE(response->was_fetched_via_spdy);
8869 EXPECT_FALSE(response->was_npn_negotiated);
8870
8871 std::string response_data;
8872 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8873 EXPECT_EQ("hello world", response_data);
8874
8875 alternative_service_vector =
8876 http_server_properties.GetAlternativeServices(http_host_port_pair);
8877 ASSERT_EQ(1u, alternative_service_vector.size());
8878 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
8879 alternative_service_vector[0].protocol);
8880 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
8881 EXPECT_EQ(443, alternative_service_vector[0].port);
8882}
8883
bnc54ec34b72015-08-26 19:34:568884// Alternative Service headers must be ignored when |use_alternative_services|
8885// is false.
8886TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
8887 session_deps_.next_protos = SpdyNextProtos();
8888 session_deps_.use_alternative_services = false;
8889
8890 std::string alternative_service_http_header =
8891 GetAlternativeServiceHttpHeader();
8892
8893 MockRead data_reads[] = {
8894 MockRead("HTTP/1.1 200 OK\r\n"),
8895 MockRead(alternative_service_http_header.c_str()),
8896 MockRead("\r\n"),
8897 MockRead("hello world"),
8898 MockRead(SYNCHRONOUS, OK),
8899 };
8900
8901 HttpRequestInfo request;
8902 request.method = "GET";
8903 request.url = GURL("http://www.example.org/");
8904 request.load_flags = 0;
8905
8906 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
8907
8908 session_deps_.socket_factory->AddSocketDataProvider(&data);
8909
8910 TestCompletionCallback callback;
8911
8912 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8913 scoped_ptr<HttpTransaction> trans(
8914 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8915
8916 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8917 EXPECT_EQ(ERR_IO_PENDING, rv);
8918
8919 HostPortPair http_host_port_pair("www.example.org", 80);
8920 HttpServerProperties& http_server_properties =
8921 *session->http_server_properties();
8922 AlternativeServiceVector alternative_service_vector =
8923 http_server_properties.GetAlternativeServices(http_host_port_pair);
8924 EXPECT_TRUE(alternative_service_vector.empty());
8925
8926 EXPECT_EQ(OK, callback.WaitForResult());
8927
8928 const HttpResponseInfo* response = trans->GetResponseInfo();
8929 ASSERT_TRUE(response != nullptr);
8930 ASSERT_TRUE(response->headers.get() != nullptr);
8931 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8932 EXPECT_FALSE(response->was_fetched_via_spdy);
8933 EXPECT_FALSE(response->was_npn_negotiated);
8934
8935 std::string response_data;
8936 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8937 EXPECT_EQ("hello world", response_data);
8938
8939 alternative_service_vector =
8940 http_server_properties.GetAlternativeServices(http_host_port_pair);
8941 EXPECT_TRUE(alternative_service_vector.empty());
8942}
8943
bncc958faa2015-07-31 18:14:528944TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
8945 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:358946 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:528947
8948 MockRead data_reads[] = {
8949 MockRead("HTTP/1.1 200 OK\r\n"),
8950 MockRead("Alt-Svc: "),
8951 MockRead(GetAlternateProtocolFromParam()),
8952 MockRead("=\"www.example.com:443\";p=1.0,"),
8953 MockRead("quic=\":1234\"\r\n\r\n"),
8954 MockRead("hello world"),
8955 MockRead(SYNCHRONOUS, OK),
8956 };
8957
8958 HttpRequestInfo request;
8959 request.method = "GET";
8960 request.url = GURL("http://www.example.org/");
8961 request.load_flags = 0;
8962
8963 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8964
8965 session_deps_.socket_factory->AddSocketDataProvider(&data);
8966
8967 TestCompletionCallback callback;
8968
8969 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8970 scoped_ptr<HttpTransaction> trans(
8971 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8972
8973 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8974 EXPECT_EQ(ERR_IO_PENDING, rv);
8975
8976 HostPortPair http_host_port_pair("www.example.org", 80);
8977 HttpServerProperties& http_server_properties =
8978 *session->http_server_properties();
8979 AlternativeServiceVector alternative_service_vector =
8980 http_server_properties.GetAlternativeServices(http_host_port_pair);
8981 EXPECT_TRUE(alternative_service_vector.empty());
8982
8983 EXPECT_EQ(OK, callback.WaitForResult());
8984
8985 const HttpResponseInfo* response = trans->GetResponseInfo();
8986 ASSERT_TRUE(response != NULL);
8987 ASSERT_TRUE(response->headers.get() != NULL);
8988 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8989 EXPECT_FALSE(response->was_fetched_via_spdy);
8990 EXPECT_FALSE(response->was_npn_negotiated);
8991
8992 std::string response_data;
8993 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8994 EXPECT_EQ("hello world", response_data);
8995
8996 alternative_service_vector =
8997 http_server_properties.GetAlternativeServices(http_host_port_pair);
8998 ASSERT_EQ(2u, alternative_service_vector.size());
8999 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9000 alternative_service_vector[0].protocol);
9001 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9002 EXPECT_EQ(443, alternative_service_vector[0].port);
9003 EXPECT_EQ(QUIC, alternative_service_vector[1].protocol);
9004 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
9005 EXPECT_EQ(1234, alternative_service_vector[1].port);
9006}
9007
bnc54ec34b72015-08-26 19:34:569008// Alternate Protocol headers must be honored even if |use_alternative_services|
9009// is false.
[email protected]23e482282013-06-14 16:08:029010TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:239011 session_deps_.next_protos = SpdyNextProtos();
bnc54ec34b72015-08-26 19:34:569012 session_deps_.use_alternative_services = false;
[email protected]a2cb8122010-03-10 17:22:429013
[email protected]8a0fc822013-06-27 20:52:439014 std::string alternate_protocol_http_header =
9015 GetAlternateProtocolHttpHeader();
9016
[email protected]564b4912010-03-09 16:30:429017 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529018 MockRead("HTTP/1.1 200 OK\r\n"),
9019 MockRead(alternate_protocol_http_header.c_str()),
9020 MockRead("\r\n"),
9021 MockRead("hello world"),
9022 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:429023 };
9024
9025 HttpRequestInfo request;
9026 request.method = "GET";
bncce36dca22015-04-21 22:11:239027 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429028 request.load_flags = 0;
9029
9030 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9031
[email protected]bb88e1d32013-05-03 23:11:079032 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:429033
[email protected]49639fa2011-12-20 23:22:419034 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429035
[email protected]bb88e1d32013-05-03 23:11:079036 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369037 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509038 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:429039
[email protected]49639fa2011-12-20 23:22:419040 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429041 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:539042
bncce36dca22015-04-21 22:11:239043 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:559044 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:539045 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:109046 AlternativeServiceVector alternative_service_vector =
9047 http_server_properties.GetAlternativeServices(http_host_port_pair);
9048 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:429049
9050 EXPECT_EQ(OK, callback.WaitForResult());
9051
9052 const HttpResponseInfo* response = trans->GetResponseInfo();
9053 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509054 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429055 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539056 EXPECT_FALSE(response->was_fetched_via_spdy);
9057 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:429058
9059 std::string response_data;
9060 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9061 EXPECT_EQ("hello world", response_data);
9062
bncd9b132e2015-07-08 05:16:109063 alternative_service_vector =
9064 http_server_properties.GetAlternativeServices(http_host_port_pair);
9065 ASSERT_EQ(1u, alternative_service_vector.size());
9066 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc181b39a2015-03-17 21:36:479067 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
bncd9b132e2015-07-08 05:16:109068 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:429069}
9070
rch89c6e102015-03-18 18:56:529071TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
9072 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359073 session_deps_.use_alternative_services = true;
rch89c6e102015-03-18 18:56:529074
9075 MockRead data_reads[] = {
9076 MockRead("HTTP/1.1 200 OK\r\n"),
9077 MockRead("Alternate-Protocol: \r\n\r\n"),
9078 MockRead("hello world"),
9079 MockRead(SYNCHRONOUS, OK),
9080 };
9081
9082 HttpRequestInfo request;
9083 request.method = "GET";
bncce36dca22015-04-21 22:11:239084 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:529085 request.load_flags = 0;
9086
9087 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9088
9089 session_deps_.socket_factory->AddSocketDataProvider(&data);
9090
9091 TestCompletionCallback callback;
9092
9093 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9094
bncce36dca22015-04-21 22:11:239095 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:529096 HttpServerProperties& http_server_properties =
9097 *session->http_server_properties();
bnccacc0992015-03-20 20:22:229098 AlternativeService alternative_service(QUIC, "", 80);
bnc7dc7e1b42015-07-28 14:43:129099 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9100 http_server_properties.SetAlternativeService(
9101 http_host_port_pair, alternative_service, 1.0, expiration);
bnccacc0992015-03-20 20:22:229102
bncd9b132e2015-07-08 05:16:109103 AlternativeServiceVector alternative_service_vector =
9104 http_server_properties.GetAlternativeServices(http_host_port_pair);
9105 ASSERT_EQ(1u, alternative_service_vector.size());
9106 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:529107
9108 scoped_ptr<HttpTransaction> trans(
9109 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9110
9111 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9112 EXPECT_EQ(ERR_IO_PENDING, rv);
9113
9114 EXPECT_EQ(OK, callback.WaitForResult());
9115
9116 const HttpResponseInfo* response = trans->GetResponseInfo();
9117 ASSERT_TRUE(response != NULL);
9118 ASSERT_TRUE(response->headers.get() != NULL);
9119 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9120 EXPECT_FALSE(response->was_fetched_via_spdy);
9121 EXPECT_FALSE(response->was_npn_negotiated);
9122
9123 std::string response_data;
9124 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9125 EXPECT_EQ("hello world", response_data);
9126
bncd9b132e2015-07-08 05:16:109127 alternative_service_vector =
9128 http_server_properties.GetAlternativeServices(http_host_port_pair);
9129 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:529130}
9131
bncc958faa2015-07-31 18:14:529132TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
9133 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359134 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529135
9136 std::string alternative_service_http_header =
9137 GetAlternativeServiceHttpHeader();
9138 std::string alternate_protocol_http_header = GetAlternateProtocolHttpHeader();
9139
9140 MockRead data_reads[] = {
9141 MockRead("HTTP/1.1 200 OK\r\n"),
9142 MockRead(alternative_service_http_header.c_str()),
9143 MockRead(alternate_protocol_http_header.c_str()),
9144 MockRead("\r\n"),
9145 MockRead("hello world"),
9146 MockRead(SYNCHRONOUS, OK),
9147 };
9148
9149 HttpRequestInfo request;
9150 request.method = "GET";
9151 request.url = GURL("http://www.example.org/");
9152 request.load_flags = 0;
9153
9154 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9155
9156 session_deps_.socket_factory->AddSocketDataProvider(&data);
9157
9158 TestCompletionCallback callback;
9159
9160 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9161 scoped_ptr<HttpTransaction> trans(
9162 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9163
9164 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9165 EXPECT_EQ(ERR_IO_PENDING, rv);
9166
9167 HostPortPair http_host_port_pair("www.example.org", 80);
9168 HttpServerProperties& http_server_properties =
9169 *session->http_server_properties();
9170 AlternativeServiceVector alternative_service_vector =
9171 http_server_properties.GetAlternativeServices(http_host_port_pair);
9172 EXPECT_TRUE(alternative_service_vector.empty());
9173
9174 EXPECT_EQ(OK, callback.WaitForResult());
9175
9176 const HttpResponseInfo* response = trans->GetResponseInfo();
9177 ASSERT_TRUE(response != NULL);
9178 ASSERT_TRUE(response->headers.get() != NULL);
9179 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9180 EXPECT_FALSE(response->was_fetched_via_spdy);
9181 EXPECT_FALSE(response->was_npn_negotiated);
9182
9183 std::string response_data;
9184 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9185 EXPECT_EQ("hello world", response_data);
9186
9187 alternative_service_vector =
9188 http_server_properties.GetAlternativeServices(http_host_port_pair);
9189 ASSERT_EQ(1u, alternative_service_vector.size());
9190 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9191 alternative_service_vector[0].protocol);
9192 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9193 EXPECT_EQ(443, alternative_service_vector[0].port);
9194}
9195
bnc54ec34b72015-08-26 19:34:569196// When |use_alternative_services| is false, do not observe alternative service
9197// entries that point to a different host.
9198TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
9199 session_deps_.use_alternative_services = false;
9200
9201 HttpRequestInfo request;
9202 request.method = "GET";
9203 request.url = GURL("http://www.example.org/");
9204 request.load_flags = 0;
9205
9206 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9207 StaticSocketDataProvider first_data;
9208 first_data.set_connect_data(mock_connect);
9209 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
9210
9211 MockRead data_reads[] = {
9212 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9213 MockRead(ASYNC, OK),
9214 };
9215 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
9216 nullptr, 0);
9217 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9218
9219 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9220
9221 base::WeakPtr<HttpServerProperties> http_server_properties =
9222 session->http_server_properties();
9223 AlternativeService alternative_service(
9224 AlternateProtocolFromNextProto(GetParam()), "different.example.org", 80);
9225 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9226 http_server_properties->SetAlternativeService(
9227 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
9228
9229 scoped_ptr<HttpTransaction> trans(
9230 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9231 TestCompletionCallback callback;
9232
9233 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9234 // The connetion to origin was refused, and the alternative service should not
9235 // be used (even though mock data are there), therefore the request should
9236 // fail.
9237 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
9238}
9239
[email protected]23e482282013-06-14 16:08:029240TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239241 MarkBrokenAlternateProtocolAndFallback) {
bnc55ff9da2015-08-19 18:42:359242 session_deps_.use_alternative_services = true;
[email protected]564b4912010-03-09 16:30:429243
9244 HttpRequestInfo request;
9245 request.method = "GET";
bncce36dca22015-04-21 22:11:239246 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429247 request.load_flags = 0;
9248
[email protected]d973e99a2012-02-17 21:02:369249 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:429250 StaticSocketDataProvider first_data;
9251 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079252 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:429253
9254 MockRead data_reads[] = {
9255 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9256 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069257 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:429258 };
9259 StaticSocketDataProvider second_data(
9260 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079261 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:429262
[email protected]bb88e1d32013-05-03 23:11:079263 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:429264
[email protected]30d4c022013-07-18 22:58:169265 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539266 session->http_server_properties();
bnc8445b3002015-03-13 01:57:099267 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:119268 // Port must be < 1024, or the header will be ignored (since initial port was
9269 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:109270 const AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239271 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bncd9b132e2015-07-08 05:16:109272 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:129273 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9274 http_server_properties->SetAlternativeService(
9275 host_port_pair, alternative_service, 1.0, expiration);
[email protected]564b4912010-03-09 16:30:429276
[email protected]262eec82013-03-19 21:01:369277 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509278 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419279 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429280
[email protected]49639fa2011-12-20 23:22:419281 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429282 EXPECT_EQ(ERR_IO_PENDING, rv);
9283 EXPECT_EQ(OK, callback.WaitForResult());
9284
9285 const HttpResponseInfo* response = trans->GetResponseInfo();
9286 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509287 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429288 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9289
9290 std::string response_data;
9291 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9292 EXPECT_EQ("hello world", response_data);
9293
bncd9b132e2015-07-08 05:16:109294 const AlternativeServiceVector alternative_service_vector =
9295 http_server_properties->GetAlternativeServices(host_port_pair);
9296 ASSERT_EQ(1u, alternative_service_vector.size());
9297 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
9298 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
9299 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:429300}
9301
bnc55ff9da2015-08-19 18:42:359302// Ensure that we are not allowed to redirect traffic via an alternate protocol
9303// to an unrestricted (port >= 1024) when the original traffic was on a
9304// restricted port (port < 1024). Ensure that we can redirect in all other
9305// cases.
[email protected]23e482282013-06-14 16:08:029306TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239307 AlternateProtocolPortRestrictedBlocked) {
bnc55ff9da2015-08-19 18:42:359308 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119309
9310 HttpRequestInfo restricted_port_request;
9311 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239312 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119313 restricted_port_request.load_flags = 0;
9314
[email protected]d973e99a2012-02-17 21:02:369315 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119316 StaticSocketDataProvider first_data;
9317 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079318 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119319
9320 MockRead data_reads[] = {
9321 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9322 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069323 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119324 };
9325 StaticSocketDataProvider second_data(
9326 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079327 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119328
[email protected]bb88e1d32013-05-03 23:11:079329 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119330
[email protected]30d4c022013-07-18 22:58:169331 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539332 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119333 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229334 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239335 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229336 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129337 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229338 http_server_properties->SetAlternativeService(
9339 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129340 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119341
[email protected]262eec82013-03-19 21:01:369342 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509343 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419344 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119345
[email protected]49639fa2011-12-20 23:22:419346 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369347 &restricted_port_request,
9348 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119349 EXPECT_EQ(ERR_IO_PENDING, rv);
9350 // Invalid change to unrestricted port should fail.
9351 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:199352}
[email protected]3912662a32011-10-04 00:51:119353
bnc55ff9da2015-08-19 18:42:359354// Ensure that we are allowed to redirect traffic via an alternate protocol to
9355// an unrestricted (port >= 1024) when the original traffic was on a restricted
9356// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:029357TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:199358 AlternateProtocolPortRestrictedPermitted) {
bnc55ff9da2015-08-19 18:42:359359 session_deps_.use_alternative_services = true;
[email protected]bb88e1d32013-05-03 23:11:079360 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:199361
9362 HttpRequestInfo restricted_port_request;
9363 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239364 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:199365 restricted_port_request.load_flags = 0;
9366
9367 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9368 StaticSocketDataProvider first_data;
9369 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079370 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:199371
9372 MockRead data_reads[] = {
9373 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9374 MockRead("hello world"),
9375 MockRead(ASYNC, OK),
9376 };
9377 StaticSocketDataProvider second_data(
9378 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079379 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:199380
[email protected]bb88e1d32013-05-03 23:11:079381 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:199382
[email protected]30d4c022013-07-18 22:58:169383 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:199384 session->http_server_properties();
9385 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229386 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239387 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229388 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129389 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229390 http_server_properties->SetAlternativeService(
9391 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129392 1.0, expiration);
[email protected]c54c6962013-02-01 04:53:199393
[email protected]262eec82013-03-19 21:01:369394 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509395 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:199396 TestCompletionCallback callback;
9397
9398 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:369399 &restricted_port_request,
9400 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:199401 // Change to unrestricted port should succeed.
9402 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119403}
9404
bnc55ff9da2015-08-19 18:42:359405// Ensure that we are not allowed to redirect traffic via an alternate protocol
9406// to an unrestricted (port >= 1024) when the original traffic was on a
9407// restricted port (port < 1024). Ensure that we can redirect in all other
9408// cases.
[email protected]23e482282013-06-14 16:08:029409TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239410 AlternateProtocolPortRestrictedAllowed) {
bnc55ff9da2015-08-19 18:42:359411 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119412
9413 HttpRequestInfo restricted_port_request;
9414 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239415 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119416 restricted_port_request.load_flags = 0;
9417
[email protected]d973e99a2012-02-17 21:02:369418 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119419 StaticSocketDataProvider first_data;
9420 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079421 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119422
9423 MockRead data_reads[] = {
9424 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9425 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069426 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119427 };
9428 StaticSocketDataProvider second_data(
9429 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079430 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119431
[email protected]bb88e1d32013-05-03 23:11:079432 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119433
[email protected]30d4c022013-07-18 22:58:169434 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539435 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119436 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229437 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239438 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229439 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129440 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229441 http_server_properties->SetAlternativeService(
9442 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129443 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119444
[email protected]262eec82013-03-19 21:01:369445 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509446 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419447 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119448
[email protected]49639fa2011-12-20 23:22:419449 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369450 &restricted_port_request,
9451 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119452 EXPECT_EQ(ERR_IO_PENDING, rv);
9453 // Valid change to restricted port should pass.
9454 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119455}
9456
bnc55ff9da2015-08-19 18:42:359457// Ensure that we are not allowed to redirect traffic via an alternate protocol
9458// to an unrestricted (port >= 1024) when the original traffic was on a
9459// restricted port (port < 1024). Ensure that we can redirect in all other
9460// cases.
[email protected]23e482282013-06-14 16:08:029461TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239462 AlternateProtocolPortUnrestrictedAllowed1) {
bnc55ff9da2015-08-19 18:42:359463 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119464
9465 HttpRequestInfo unrestricted_port_request;
9466 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239467 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119468 unrestricted_port_request.load_flags = 0;
9469
[email protected]d973e99a2012-02-17 21:02:369470 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119471 StaticSocketDataProvider first_data;
9472 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079473 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119474
9475 MockRead data_reads[] = {
9476 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9477 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069478 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119479 };
9480 StaticSocketDataProvider second_data(
9481 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079482 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119483
[email protected]bb88e1d32013-05-03 23:11:079484 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119485
[email protected]30d4c022013-07-18 22:58:169486 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539487 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119488 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229489 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239490 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229491 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129492 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229493 http_server_properties->SetAlternativeService(
9494 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129495 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119496
[email protected]262eec82013-03-19 21:01:369497 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509498 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419499 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119500
[email protected]49639fa2011-12-20 23:22:419501 int rv = trans->Start(
9502 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119503 EXPECT_EQ(ERR_IO_PENDING, rv);
9504 // Valid change to restricted port should pass.
9505 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119506}
9507
bnc55ff9da2015-08-19 18:42:359508// Ensure that we are not allowed to redirect traffic via an alternate protocol
9509// to an unrestricted (port >= 1024) when the original traffic was on a
9510// restricted port (port < 1024). Ensure that we can redirect in all other
9511// cases.
[email protected]23e482282013-06-14 16:08:029512TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239513 AlternateProtocolPortUnrestrictedAllowed2) {
bnc55ff9da2015-08-19 18:42:359514 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119515
9516 HttpRequestInfo unrestricted_port_request;
9517 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239518 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119519 unrestricted_port_request.load_flags = 0;
9520
[email protected]d973e99a2012-02-17 21:02:369521 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119522 StaticSocketDataProvider first_data;
9523 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079524 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119525
9526 MockRead data_reads[] = {
9527 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9528 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069529 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119530 };
9531 StaticSocketDataProvider second_data(
9532 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079533 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119534
[email protected]bb88e1d32013-05-03 23:11:079535 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119536
[email protected]30d4c022013-07-18 22:58:169537 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539538 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:229539 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:229540 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239541 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229542 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129543 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229544 http_server_properties->SetAlternativeService(
9545 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129546 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119547
[email protected]262eec82013-03-19 21:01:369548 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509549 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419550 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119551
[email protected]49639fa2011-12-20 23:22:419552 int rv = trans->Start(
9553 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119554 EXPECT_EQ(ERR_IO_PENDING, rv);
9555 // Valid change to an unrestricted port should pass.
9556 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119557}
9558
bnc55ff9da2015-08-19 18:42:359559// Ensure that we are not allowed to redirect traffic via an alternate protocol
9560// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
9561// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239562TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bnc55ff9da2015-08-19 18:42:359563 session_deps_.use_alternative_services = true;
[email protected]eb6234e2012-01-19 01:50:029564
9565 HttpRequestInfo request;
9566 request.method = "GET";
bncce36dca22015-04-21 22:11:239567 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029568 request.load_flags = 0;
9569
9570 // The alternate protocol request will error out before we attempt to connect,
9571 // so only the standard HTTP request will try to connect.
9572 MockRead data_reads[] = {
9573 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9574 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069575 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029576 };
9577 StaticSocketDataProvider data(
9578 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079579 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029580
[email protected]bb88e1d32013-05-03 23:11:079581 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029582
[email protected]30d4c022013-07-18 22:58:169583 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029584 session->http_server_properties();
9585 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229586 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239587 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229588 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:129589 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229590 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:129591 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
[email protected]eb6234e2012-01-19 01:50:029592
[email protected]262eec82013-03-19 21:01:369593 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509594 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029595 TestCompletionCallback callback;
9596
9597 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9598 EXPECT_EQ(ERR_IO_PENDING, rv);
9599 // The HTTP request should succeed.
9600 EXPECT_EQ(OK, callback.WaitForResult());
9601
[email protected]eb6234e2012-01-19 01:50:029602 const HttpResponseInfo* response = trans->GetResponseInfo();
9603 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509604 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029605 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9606
9607 std::string response_data;
9608 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9609 EXPECT_EQ("hello world", response_data);
9610}
9611
[email protected]23e482282013-06-14 16:08:029612TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359613 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239614 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549615
9616 HttpRequestInfo request;
9617 request.method = "GET";
bncce36dca22015-04-21 22:11:239618 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549619 request.load_flags = 0;
9620
[email protected]8a0fc822013-06-27 20:52:439621 std::string alternate_protocol_http_header =
9622 GetAlternateProtocolHttpHeader();
9623
[email protected]2ff8b312010-04-26 22:20:549624 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529625 MockRead("HTTP/1.1 200 OK\r\n"),
9626 MockRead(alternate_protocol_http_header.c_str()),
9627 MockRead("\r\n"),
9628 MockRead("hello world"),
9629 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9630 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:549631
9632 StaticSocketDataProvider first_transaction(
9633 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079634 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549635
[email protected]8ddf8322012-02-23 18:08:069636 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029637 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239638 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9639 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079640 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549641
[email protected]cdf8f7e72013-05-23 10:56:469642 scoped_ptr<SpdyFrame> req(
9643 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139644 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549645
[email protected]23e482282013-06-14 16:08:029646 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9647 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549648 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139649 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549650 };
9651
rch8e6c6c42015-05-01 14:05:139652 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9653 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079654 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549655
[email protected]d973e99a2012-02-17 21:02:369656 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559657 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9658 NULL, 0, NULL, 0);
9659 hanging_non_alternate_protocol_socket.set_connect_data(
9660 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079661 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559662 &hanging_non_alternate_protocol_socket);
9663
[email protected]49639fa2011-12-20 23:22:419664 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549665
[email protected]bb88e1d32013-05-03 23:11:079666 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369667 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509668 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549669
[email protected]49639fa2011-12-20 23:22:419670 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549671 EXPECT_EQ(ERR_IO_PENDING, rv);
9672 EXPECT_EQ(OK, callback.WaitForResult());
9673
9674 const HttpResponseInfo* response = trans->GetResponseInfo();
9675 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509676 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549677 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9678
9679 std::string response_data;
9680 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9681 EXPECT_EQ("hello world", response_data);
9682
[email protected]90499482013-06-01 00:39:509683 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549684
[email protected]49639fa2011-12-20 23:22:419685 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549686 EXPECT_EQ(ERR_IO_PENDING, rv);
9687 EXPECT_EQ(OK, callback.WaitForResult());
9688
9689 response = trans->GetResponseInfo();
9690 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509691 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549692 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539693 EXPECT_TRUE(response->was_fetched_via_spdy);
9694 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549695
9696 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9697 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549698}
9699
[email protected]23e482282013-06-14 16:08:029700TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc55ff9da2015-08-19 18:42:359701 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239702 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559703
9704 HttpRequestInfo request;
9705 request.method = "GET";
bncce36dca22015-04-21 22:11:239706 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559707 request.load_flags = 0;
9708
[email protected]8a0fc822013-06-27 20:52:439709 std::string alternate_protocol_http_header =
9710 GetAlternateProtocolHttpHeader();
9711
[email protected]2d6728692011-03-12 01:39:559712 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529713 MockRead("HTTP/1.1 200 OK\r\n"),
9714 MockRead(alternate_protocol_http_header.c_str()),
9715 MockRead("\r\n"),
9716 MockRead("hello world"),
9717 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9718 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559719 };
9720
9721 StaticSocketDataProvider first_transaction(
9722 data_reads, arraysize(data_reads), NULL, 0);
9723 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079724 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559725
[email protected]d973e99a2012-02-17 21:02:369726 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559727 StaticSocketDataProvider hanging_socket(
9728 NULL, 0, NULL, 0);
9729 hanging_socket.set_connect_data(never_finishing_connect);
9730 // Socket 2 and 3 are the hanging Alternate-Protocol and
9731 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079732 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9733 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559734
[email protected]8ddf8322012-02-23 18:08:069735 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029736 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239737 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9738 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079739 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559740
[email protected]cdf8f7e72013-05-23 10:56:469741 scoped_ptr<SpdyFrame> req1(
9742 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9743 scoped_ptr<SpdyFrame> req2(
9744 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559745 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139746 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559747 };
[email protected]23e482282013-06-14 16:08:029748 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9749 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9750 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9751 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559752 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139753 CreateMockRead(*resp1, 2),
9754 CreateMockRead(*data1, 3),
9755 CreateMockRead(*resp2, 4),
9756 CreateMockRead(*data2, 5),
9757 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559758 };
9759
rch8e6c6c42015-05-01 14:05:139760 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9761 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559762 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079763 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559764
9765 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079766 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559767
[email protected]bb88e1d32013-05-03 23:11:079768 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419769 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509770 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559771
[email protected]49639fa2011-12-20 23:22:419772 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559773 EXPECT_EQ(ERR_IO_PENDING, rv);
9774 EXPECT_EQ(OK, callback1.WaitForResult());
9775
9776 const HttpResponseInfo* response = trans1.GetResponseInfo();
9777 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509778 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559779 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9780
9781 std::string response_data;
9782 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9783 EXPECT_EQ("hello world", response_data);
9784
[email protected]49639fa2011-12-20 23:22:419785 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509786 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419787 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559788 EXPECT_EQ(ERR_IO_PENDING, rv);
9789
[email protected]49639fa2011-12-20 23:22:419790 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509791 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419792 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559793 EXPECT_EQ(ERR_IO_PENDING, rv);
9794
9795 EXPECT_EQ(OK, callback2.WaitForResult());
9796 EXPECT_EQ(OK, callback3.WaitForResult());
9797
9798 response = trans2.GetResponseInfo();
9799 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509800 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559801 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9802 EXPECT_TRUE(response->was_fetched_via_spdy);
9803 EXPECT_TRUE(response->was_npn_negotiated);
9804 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9805 EXPECT_EQ("hello!", response_data);
9806
9807 response = trans3.GetResponseInfo();
9808 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509809 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559810 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9811 EXPECT_TRUE(response->was_fetched_via_spdy);
9812 EXPECT_TRUE(response->was_npn_negotiated);
9813 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9814 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559815}
9816
[email protected]23e482282013-06-14 16:08:029817TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359818 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239819 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559820
9821 HttpRequestInfo request;
9822 request.method = "GET";
bncce36dca22015-04-21 22:11:239823 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559824 request.load_flags = 0;
9825
[email protected]8a0fc822013-06-27 20:52:439826 std::string alternate_protocol_http_header =
9827 GetAlternateProtocolHttpHeader();
9828
[email protected]2d6728692011-03-12 01:39:559829 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529830 MockRead("HTTP/1.1 200 OK\r\n"),
9831 MockRead(alternate_protocol_http_header.c_str()),
9832 MockRead("\r\n"),
9833 MockRead("hello world"),
9834 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9835 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559836 };
9837
9838 StaticSocketDataProvider first_transaction(
9839 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079840 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559841
[email protected]8ddf8322012-02-23 18:08:069842 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029843 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079844 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559845
[email protected]d973e99a2012-02-17 21:02:369846 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559847 StaticSocketDataProvider hanging_alternate_protocol_socket(
9848 NULL, 0, NULL, 0);
9849 hanging_alternate_protocol_socket.set_connect_data(
9850 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079851 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559852 &hanging_alternate_protocol_socket);
9853
9854 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079855 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559856
[email protected]49639fa2011-12-20 23:22:419857 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559858
[email protected]bb88e1d32013-05-03 23:11:079859 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369860 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509861 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559862
[email protected]49639fa2011-12-20 23:22:419863 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559864 EXPECT_EQ(ERR_IO_PENDING, rv);
9865 EXPECT_EQ(OK, callback.WaitForResult());
9866
9867 const HttpResponseInfo* response = trans->GetResponseInfo();
9868 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509869 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559870 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9871
9872 std::string response_data;
9873 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9874 EXPECT_EQ("hello world", response_data);
9875
[email protected]90499482013-06-01 00:39:509876 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559877
[email protected]49639fa2011-12-20 23:22:419878 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559879 EXPECT_EQ(ERR_IO_PENDING, rv);
9880 EXPECT_EQ(OK, callback.WaitForResult());
9881
9882 response = trans->GetResponseInfo();
9883 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509884 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559885 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9886 EXPECT_FALSE(response->was_fetched_via_spdy);
9887 EXPECT_FALSE(response->was_npn_negotiated);
9888
9889 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9890 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559891}
9892
[email protected]631f1322010-04-30 17:59:119893class CapturingProxyResolver : public ProxyResolver {
9894 public:
sammce90c9212015-05-27 23:43:359895 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:209896 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119897
dchengb03027d2014-10-21 12:00:209898 int GetProxyForURL(const GURL& url,
9899 ProxyInfo* results,
9900 const CompletionCallback& callback,
9901 RequestHandle* request,
9902 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409903 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9904 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429905 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119906 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429907 return OK;
[email protected]631f1322010-04-30 17:59:119908 }
9909
dchengb03027d2014-10-21 12:00:209910 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119911
dchengb03027d2014-10-21 12:00:209912 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179913 NOTREACHED();
9914 return LOAD_STATE_IDLE;
9915 }
9916
[email protected]24476402010-07-20 20:55:179917 const std::vector<GURL>& resolved() const { return resolved_; }
9918
9919 private:
[email protected]631f1322010-04-30 17:59:119920 std::vector<GURL> resolved_;
9921
9922 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9923};
9924
sammce64b2362015-04-29 03:50:239925class CapturingProxyResolverFactory : public ProxyResolverFactory {
9926 public:
9927 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
9928 : ProxyResolverFactory(false), resolver_(resolver) {}
9929
9930 int CreateProxyResolver(
9931 const scoped_refptr<ProxyResolverScriptData>& pac_script,
9932 scoped_ptr<ProxyResolver>* resolver,
9933 const net::CompletionCallback& callback,
9934 scoped_ptr<Request>* request) override {
9935 resolver->reset(new ForwardingProxyResolver(resolver_));
9936 return OK;
9937 }
9938
9939 private:
9940 ProxyResolver* resolver_;
9941};
9942
[email protected]23e482282013-06-14 16:08:029943TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239944 UseAlternateProtocolForTunneledNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359945 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239946 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119947
9948 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429949 proxy_config.set_auto_detect(true);
9950 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119951
sammc5dd160c2015-04-02 02:43:139952 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:079953 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:139954 new ProxyConfigServiceFixed(proxy_config),
9955 make_scoped_ptr(
sammce64b2362015-04-29 03:50:239956 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:389957 NULL));
vishal.b62985ca92015-04-17 08:45:519958 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079959 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119960
9961 HttpRequestInfo request;
9962 request.method = "GET";
bncce36dca22015-04-21 22:11:239963 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:119964 request.load_flags = 0;
9965
[email protected]8a0fc822013-06-27 20:52:439966 std::string alternate_protocol_http_header =
9967 GetAlternateProtocolHttpHeader();
9968
[email protected]631f1322010-04-30 17:59:119969 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529970 MockRead("HTTP/1.1 200 OK\r\n"),
9971 MockRead(alternate_protocol_http_header.c_str()),
9972 MockRead("\r\n"),
9973 MockRead("hello world"),
9974 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9975 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119976 };
9977
9978 StaticSocketDataProvider first_transaction(
9979 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079980 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119981
[email protected]8ddf8322012-02-23 18:08:069982 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029983 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239984 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9985 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079986 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119987
[email protected]cdf8f7e72013-05-23 10:56:469988 scoped_ptr<SpdyFrame> req(
9989 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119990 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139991 MockWrite(ASYNC, 0,
9992 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9993 "Host: www.example.org\r\n"
9994 "Proxy-Connection: keep-alive\r\n\r\n"),
9995 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:119996 };
9997
[email protected]d911f1b2010-05-05 22:39:429998 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9999
[email protected]23e482282013-06-14 16:08:0210000 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10001 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1110002 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310003 MockRead(ASYNC, 1, kCONNECTResponse),
10004 CreateMockRead(*resp.get(), 3),
10005 CreateMockRead(*data.get(), 4),
10006 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1110007 };
10008
rch8e6c6c42015-05-01 14:05:1310009 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10010 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710011 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1110012
[email protected]d973e99a2012-02-17 21:02:3610013 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510014 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10015 NULL, 0, NULL, 0);
10016 hanging_non_alternate_protocol_socket.set_connect_data(
10017 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710018 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510019 &hanging_non_alternate_protocol_socket);
10020
[email protected]49639fa2011-12-20 23:22:4110021 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1110022
[email protected]bb88e1d32013-05-03 23:11:0710023 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610024 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010025 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110026
[email protected]49639fa2011-12-20 23:22:4110027 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110028 EXPECT_EQ(ERR_IO_PENDING, rv);
10029 EXPECT_EQ(OK, callback.WaitForResult());
10030
10031 const HttpResponseInfo* response = trans->GetResponseInfo();
10032 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010033 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110034 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310035 EXPECT_FALSE(response->was_fetched_via_spdy);
10036 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110037
10038 std::string response_data;
10039 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10040 EXPECT_EQ("hello world", response_data);
10041
[email protected]90499482013-06-01 00:39:5010042 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110043
[email protected]49639fa2011-12-20 23:22:4110044 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110045 EXPECT_EQ(ERR_IO_PENDING, rv);
10046 EXPECT_EQ(OK, callback.WaitForResult());
10047
10048 response = trans->GetResponseInfo();
10049 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010050 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110051 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310052 EXPECT_TRUE(response->was_fetched_via_spdy);
10053 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110054
10055 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10056 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1310057 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2310058 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310059 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2310060 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310061 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1110062
[email protected]029c83b62013-01-24 05:28:2010063 LoadTimingInfo load_timing_info;
10064 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10065 TestLoadTimingNotReusedWithPac(load_timing_info,
10066 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1110067}
[email protected]631f1322010-04-30 17:59:1110068
[email protected]23e482282013-06-14 16:08:0210069TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:5410070 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
bnc55ff9da2015-08-19 18:42:3510071 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310072 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:5410073
10074 HttpRequestInfo request;
10075 request.method = "GET";
bncce36dca22015-04-21 22:11:2310076 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410077 request.load_flags = 0;
10078
[email protected]8a0fc822013-06-27 20:52:4310079 std::string alternate_protocol_http_header =
10080 GetAlternateProtocolHttpHeader();
10081
[email protected]2ff8b312010-04-26 22:20:5410082 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210083 MockRead("HTTP/1.1 200 OK\r\n"),
10084 MockRead(alternate_protocol_http_header.c_str()),
10085 MockRead("\r\n"),
10086 MockRead("hello world"),
10087 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5410088 };
10089
10090 StaticSocketDataProvider first_transaction(
10091 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710092 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410093
[email protected]8ddf8322012-02-23 18:08:0610094 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210095 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310096 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10097 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710098 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410099
[email protected]cdf8f7e72013-05-23 10:56:4610100 scoped_ptr<SpdyFrame> req(
10101 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310102 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410103
[email protected]23e482282013-06-14 16:08:0210104 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10105 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410106 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310107 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410108 };
10109
rch8e6c6c42015-05-01 14:05:1310110 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10111 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710112 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410113
[email protected]83039bb2011-12-09 18:43:5510114 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410115
[email protected]bb88e1d32013-05-03 23:11:0710116 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5410117
[email protected]262eec82013-03-19 21:01:3610118 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010119 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410120
[email protected]49639fa2011-12-20 23:22:4110121 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410122 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110123 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410124
10125 const HttpResponseInfo* response = trans->GetResponseInfo();
10126 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010127 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410128 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10129
10130 std::string response_data;
10131 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10132 EXPECT_EQ("hello world", response_data);
10133
10134 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310135 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010136 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310137 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710138 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610139 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3810140
[email protected]90499482013-06-01 00:39:5010141 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410142
[email protected]49639fa2011-12-20 23:22:4110143 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410144 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110145 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410146
10147 response = trans->GetResponseInfo();
10148 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010149 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410150 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310151 EXPECT_TRUE(response->was_fetched_via_spdy);
10152 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410153
10154 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10155 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4210156}
10157
[email protected]044de0642010-06-17 10:42:1510158// GenerateAuthToken is a mighty big test.
10159// It tests all permutation of GenerateAuthToken behavior:
10160// - Synchronous and Asynchronous completion.
10161// - OK or error on completion.
10162// - Direct connection, non-authenticating proxy, and authenticating proxy.
10163// - HTTP or HTTPS backend (to include proxy tunneling).
10164// - Non-authenticating and authenticating backend.
10165//
[email protected]fe3b7dc2012-02-03 19:52:0910166// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1510167// problems generating an auth token for an authenticating proxy, we don't
10168// need to test all permutations of the backend server).
10169//
10170// The test proceeds by going over each of the configuration cases, and
10171// potentially running up to three rounds in each of the tests. The TestConfig
10172// specifies both the configuration for the test as well as the expectations
10173// for the results.
[email protected]23e482282013-06-14 16:08:0210174TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5010175 static const char kServer[] = "http://www.example.com";
10176 static const char kSecureServer[] = "https://www.example.com";
10177 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1510178 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
10179
10180 enum AuthTiming {
10181 AUTH_NONE,
10182 AUTH_SYNC,
10183 AUTH_ASYNC,
10184 };
10185
10186 const MockWrite kGet(
10187 "GET / HTTP/1.1\r\n"
10188 "Host: www.example.com\r\n"
10189 "Connection: keep-alive\r\n\r\n");
10190 const MockWrite kGetProxy(
10191 "GET http://www.example.com/ HTTP/1.1\r\n"
10192 "Host: www.example.com\r\n"
10193 "Proxy-Connection: keep-alive\r\n\r\n");
10194 const MockWrite kGetAuth(
10195 "GET / HTTP/1.1\r\n"
10196 "Host: www.example.com\r\n"
10197 "Connection: keep-alive\r\n"
10198 "Authorization: auth_token\r\n\r\n");
10199 const MockWrite kGetProxyAuth(
10200 "GET http://www.example.com/ HTTP/1.1\r\n"
10201 "Host: www.example.com\r\n"
10202 "Proxy-Connection: keep-alive\r\n"
10203 "Proxy-Authorization: auth_token\r\n\r\n");
10204 const MockWrite kGetAuthThroughProxy(
10205 "GET http://www.example.com/ HTTP/1.1\r\n"
10206 "Host: www.example.com\r\n"
10207 "Proxy-Connection: keep-alive\r\n"
10208 "Authorization: auth_token\r\n\r\n");
10209 const MockWrite kGetAuthWithProxyAuth(
10210 "GET http://www.example.com/ HTTP/1.1\r\n"
10211 "Host: www.example.com\r\n"
10212 "Proxy-Connection: keep-alive\r\n"
10213 "Proxy-Authorization: auth_token\r\n"
10214 "Authorization: auth_token\r\n\r\n");
10215 const MockWrite kConnect(
10216 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10217 "Host: www.example.com\r\n"
10218 "Proxy-Connection: keep-alive\r\n\r\n");
10219 const MockWrite kConnectProxyAuth(
10220 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10221 "Host: www.example.com\r\n"
10222 "Proxy-Connection: keep-alive\r\n"
10223 "Proxy-Authorization: auth_token\r\n\r\n");
10224
10225 const MockRead kSuccess(
10226 "HTTP/1.1 200 OK\r\n"
10227 "Content-Type: text/html; charset=iso-8859-1\r\n"
10228 "Content-Length: 3\r\n\r\n"
10229 "Yes");
10230 const MockRead kFailure(
10231 "Should not be called.");
10232 const MockRead kServerChallenge(
10233 "HTTP/1.1 401 Unauthorized\r\n"
10234 "WWW-Authenticate: Mock realm=server\r\n"
10235 "Content-Type: text/html; charset=iso-8859-1\r\n"
10236 "Content-Length: 14\r\n\r\n"
10237 "Unauthorized\r\n");
10238 const MockRead kProxyChallenge(
10239 "HTTP/1.1 407 Unauthorized\r\n"
10240 "Proxy-Authenticate: Mock realm=proxy\r\n"
10241 "Proxy-Connection: close\r\n"
10242 "Content-Type: text/html; charset=iso-8859-1\r\n"
10243 "Content-Length: 14\r\n\r\n"
10244 "Unauthorized\r\n");
10245 const MockRead kProxyConnected(
10246 "HTTP/1.1 200 Connection Established\r\n\r\n");
10247
10248 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
10249 // no constructors, but the C++ compiler on Windows warns about
10250 // unspecified data in compound literals. So, moved to using constructors,
10251 // and TestRound's created with the default constructor should not be used.
10252 struct TestRound {
10253 TestRound()
10254 : expected_rv(ERR_UNEXPECTED),
10255 extra_write(NULL),
10256 extra_read(NULL) {
10257 }
10258 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10259 int expected_rv_arg)
10260 : write(write_arg),
10261 read(read_arg),
10262 expected_rv(expected_rv_arg),
10263 extra_write(NULL),
10264 extra_read(NULL) {
10265 }
10266 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10267 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0110268 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1510269 : write(write_arg),
10270 read(read_arg),
10271 expected_rv(expected_rv_arg),
10272 extra_write(extra_write_arg),
10273 extra_read(extra_read_arg) {
10274 }
10275 MockWrite write;
10276 MockRead read;
10277 int expected_rv;
10278 const MockWrite* extra_write;
10279 const MockRead* extra_read;
10280 };
10281
10282 static const int kNoSSL = 500;
10283
10284 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5110285 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1510286 AuthTiming proxy_auth_timing;
10287 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5110288 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1510289 AuthTiming server_auth_timing;
10290 int server_auth_rv;
10291 int num_auth_rounds;
10292 int first_ssl_round;
10293 TestRound rounds[3];
10294 } test_configs[] = {
10295 // Non-authenticating HTTP server with a direct connection.
10296 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10297 { TestRound(kGet, kSuccess, OK)}},
10298 // Authenticating HTTP server with a direct connection.
10299 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10300 { TestRound(kGet, kServerChallenge, OK),
10301 TestRound(kGetAuth, kSuccess, OK)}},
10302 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10303 { TestRound(kGet, kServerChallenge, OK),
10304 TestRound(kGetAuth, kFailure, kAuthErr)}},
10305 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10306 { TestRound(kGet, kServerChallenge, OK),
10307 TestRound(kGetAuth, kSuccess, OK)}},
10308 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10309 { TestRound(kGet, kServerChallenge, OK),
10310 TestRound(kGetAuth, kFailure, kAuthErr)}},
10311 // Non-authenticating HTTP server through a non-authenticating proxy.
10312 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10313 { TestRound(kGetProxy, kSuccess, OK)}},
10314 // Authenticating HTTP server through a non-authenticating proxy.
10315 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10316 { TestRound(kGetProxy, kServerChallenge, OK),
10317 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10318 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10319 { TestRound(kGetProxy, kServerChallenge, OK),
10320 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10321 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10322 { TestRound(kGetProxy, kServerChallenge, OK),
10323 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10324 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10325 { TestRound(kGetProxy, kServerChallenge, OK),
10326 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10327 // Non-authenticating HTTP server through an authenticating proxy.
10328 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10329 { TestRound(kGetProxy, kProxyChallenge, OK),
10330 TestRound(kGetProxyAuth, kSuccess, OK)}},
10331 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10332 { TestRound(kGetProxy, kProxyChallenge, OK),
10333 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10334 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10335 { TestRound(kGetProxy, kProxyChallenge, OK),
10336 TestRound(kGetProxyAuth, kSuccess, OK)}},
10337 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10338 { TestRound(kGetProxy, kProxyChallenge, OK),
10339 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10340 // Authenticating HTTP server through an authenticating proxy.
10341 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10342 { TestRound(kGetProxy, kProxyChallenge, OK),
10343 TestRound(kGetProxyAuth, kServerChallenge, OK),
10344 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10345 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10346 { TestRound(kGetProxy, kProxyChallenge, OK),
10347 TestRound(kGetProxyAuth, kServerChallenge, OK),
10348 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10349 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10350 { TestRound(kGetProxy, kProxyChallenge, OK),
10351 TestRound(kGetProxyAuth, kServerChallenge, OK),
10352 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10353 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10354 { TestRound(kGetProxy, kProxyChallenge, OK),
10355 TestRound(kGetProxyAuth, kServerChallenge, OK),
10356 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10357 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10358 { TestRound(kGetProxy, kProxyChallenge, OK),
10359 TestRound(kGetProxyAuth, kServerChallenge, OK),
10360 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10361 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10362 { TestRound(kGetProxy, kProxyChallenge, OK),
10363 TestRound(kGetProxyAuth, kServerChallenge, OK),
10364 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10365 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10366 { TestRound(kGetProxy, kProxyChallenge, OK),
10367 TestRound(kGetProxyAuth, kServerChallenge, OK),
10368 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10369 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10370 { TestRound(kGetProxy, kProxyChallenge, OK),
10371 TestRound(kGetProxyAuth, kServerChallenge, OK),
10372 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10373 // Non-authenticating HTTPS server with a direct connection.
10374 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10375 { TestRound(kGet, kSuccess, OK)}},
10376 // Authenticating HTTPS server with a direct connection.
10377 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10378 { TestRound(kGet, kServerChallenge, OK),
10379 TestRound(kGetAuth, kSuccess, OK)}},
10380 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10381 { TestRound(kGet, kServerChallenge, OK),
10382 TestRound(kGetAuth, kFailure, kAuthErr)}},
10383 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10384 { TestRound(kGet, kServerChallenge, OK),
10385 TestRound(kGetAuth, kSuccess, OK)}},
10386 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10387 { TestRound(kGet, kServerChallenge, OK),
10388 TestRound(kGetAuth, kFailure, kAuthErr)}},
10389 // Non-authenticating HTTPS server with a non-authenticating proxy.
10390 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10391 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
10392 // Authenticating HTTPS server through a non-authenticating proxy.
10393 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10394 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10395 TestRound(kGetAuth, kSuccess, OK)}},
10396 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10397 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10398 TestRound(kGetAuth, kFailure, kAuthErr)}},
10399 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10400 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10401 TestRound(kGetAuth, kSuccess, OK)}},
10402 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10403 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10404 TestRound(kGetAuth, kFailure, kAuthErr)}},
10405 // Non-Authenticating HTTPS server through an authenticating proxy.
10406 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10407 { TestRound(kConnect, kProxyChallenge, OK),
10408 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10409 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10410 { TestRound(kConnect, kProxyChallenge, OK),
10411 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10412 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10413 { TestRound(kConnect, kProxyChallenge, OK),
10414 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10415 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10416 { TestRound(kConnect, kProxyChallenge, OK),
10417 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10418 // Authenticating HTTPS server through an authenticating proxy.
10419 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10420 { TestRound(kConnect, kProxyChallenge, OK),
10421 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10422 &kGet, &kServerChallenge),
10423 TestRound(kGetAuth, kSuccess, OK)}},
10424 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10425 { TestRound(kConnect, kProxyChallenge, OK),
10426 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10427 &kGet, &kServerChallenge),
10428 TestRound(kGetAuth, kFailure, kAuthErr)}},
10429 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10430 { TestRound(kConnect, kProxyChallenge, OK),
10431 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10432 &kGet, &kServerChallenge),
10433 TestRound(kGetAuth, kSuccess, OK)}},
10434 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10435 { TestRound(kConnect, kProxyChallenge, OK),
10436 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10437 &kGet, &kServerChallenge),
10438 TestRound(kGetAuth, kFailure, kAuthErr)}},
10439 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10440 { TestRound(kConnect, kProxyChallenge, OK),
10441 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10442 &kGet, &kServerChallenge),
10443 TestRound(kGetAuth, kSuccess, OK)}},
10444 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10445 { TestRound(kConnect, kProxyChallenge, OK),
10446 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10447 &kGet, &kServerChallenge),
10448 TestRound(kGetAuth, kFailure, kAuthErr)}},
10449 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10450 { TestRound(kConnect, kProxyChallenge, OK),
10451 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10452 &kGet, &kServerChallenge),
10453 TestRound(kGetAuth, kSuccess, OK)}},
10454 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10455 { TestRound(kConnect, kProxyChallenge, OK),
10456 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10457 &kGet, &kServerChallenge),
10458 TestRound(kGetAuth, kFailure, kAuthErr)}},
10459 };
10460
viettrungluue4a8b882014-10-16 06:17:3810461 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810462 HttpAuthHandlerMock::Factory* auth_factory(
10463 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710464 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510465 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610466
10467 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510468 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810469 for (int n = 0; n < 2; n++) {
10470 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10471 std::string auth_challenge = "Mock realm=proxy";
10472 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410473 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10474 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810475 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10476 origin, BoundNetLog());
10477 auth_handler->SetGenerateExpectation(
10478 test_config.proxy_auth_timing == AUTH_ASYNC,
10479 test_config.proxy_auth_rv);
10480 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10481 }
[email protected]044de0642010-06-17 10:42:1510482 }
10483 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010484 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510485 std::string auth_challenge = "Mock realm=server";
10486 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410487 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10488 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510489 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10490 origin, BoundNetLog());
10491 auth_handler->SetGenerateExpectation(
10492 test_config.server_auth_timing == AUTH_ASYNC,
10493 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810494 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510495 }
10496 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:0710497 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:1210498 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:1510499 } else {
[email protected]bb88e1d32013-05-03 23:11:0710500 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:1510501 }
10502
10503 HttpRequestInfo request;
10504 request.method = "GET";
10505 request.url = GURL(test_config.server_url);
10506 request.load_flags = 0;
10507
[email protected]bb88e1d32013-05-03 23:11:0710508 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110509 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510510
rchcb68dc62015-05-21 04:45:3610511 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
10512
10513 std::vector<std::vector<MockRead>> mock_reads(1);
10514 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1510515 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10516 const TestRound& read_write_round = test_config.rounds[round];
10517
10518 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3610519 mock_reads.back().push_back(read_write_round.read);
10520 mock_writes.back().push_back(read_write_round.write);
10521
10522 // kProxyChallenge uses Proxy-Connection: close which means that the
10523 // socket is closed and a new one will be created for the next request.
mmenkee0b5c882015-08-26 20:29:1110524 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3610525 mock_reads.push_back(std::vector<MockRead>());
10526 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1510527 }
10528
rchcb68dc62015-05-21 04:45:3610529 if (read_write_round.extra_read) {
10530 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1510531 }
rchcb68dc62015-05-21 04:45:3610532 if (read_write_round.extra_write) {
10533 mock_writes.back().push_back(*read_write_round.extra_write);
10534 }
[email protected]044de0642010-06-17 10:42:1510535
10536 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1510537 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710538 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510539 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3610540 }
[email protected]044de0642010-06-17 10:42:1510541
rchcb68dc62015-05-21 04:45:3610542 ScopedVector<StaticSocketDataProvider> data_providers;
10543 for (size_t i = 0; i < mock_reads.size(); ++i) {
10544 data_providers.push_back(new StaticSocketDataProvider(
10545 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
10546 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
10547 session_deps_.socket_factory->AddSocketDataProvider(
10548 data_providers.back());
10549 }
10550
10551 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10552 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1510553 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110554 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510555 int rv;
10556 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110557 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510558 } else {
[email protected]49639fa2011-12-20 23:22:4110559 rv = trans.RestartWithAuth(
10560 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510561 }
10562 if (rv == ERR_IO_PENDING)
10563 rv = callback.WaitForResult();
10564
10565 // Compare results with expected data.
10566 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010567 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5510568 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1510569 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10570 continue;
10571 }
10572 if (round + 1 < test_config.num_auth_rounds) {
10573 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10574 } else {
10575 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10576 }
10577 }
[email protected]e5ae96a2010-04-14 20:12:4510578 }
10579}
10580
[email protected]23e482282013-06-14 16:08:0210581TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410582 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410583 HttpAuthHandlerMock::Factory* auth_factory(
10584 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710585 session_deps_.http_auth_handler_factory.reset(auth_factory);
10586 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10587 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10588 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410589
10590 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10591 auth_handler->set_connection_based(true);
10592 std::string auth_challenge = "Mock realm=server";
10593 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410594 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10595 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410596 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10597 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810598 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410599
[email protected]c871bce92010-07-15 21:51:1410600 int rv = OK;
10601 const HttpResponseInfo* response = NULL;
10602 HttpRequestInfo request;
10603 request.method = "GET";
10604 request.url = origin;
10605 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710606
[email protected]bb88e1d32013-05-03 23:11:0710607 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010608
10609 // Use a TCP Socket Pool with only one connection per group. This is used
10610 // to validate that the TCP socket is not released to the pool between
10611 // each round of multi-round authentication.
10612 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810613 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010614 50, // Max sockets for pool
10615 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710616 session_deps_.host_resolver.get(),
10617 session_deps_.socket_factory.get(),
10618 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410619 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10620 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210621 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110622 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010623
[email protected]262eec82013-03-19 21:01:3610624 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010625 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110626 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410627
10628 const MockWrite kGet(
10629 "GET / HTTP/1.1\r\n"
10630 "Host: www.example.com\r\n"
10631 "Connection: keep-alive\r\n\r\n");
10632 const MockWrite kGetAuth(
10633 "GET / HTTP/1.1\r\n"
10634 "Host: www.example.com\r\n"
10635 "Connection: keep-alive\r\n"
10636 "Authorization: auth_token\r\n\r\n");
10637
10638 const MockRead kServerChallenge(
10639 "HTTP/1.1 401 Unauthorized\r\n"
10640 "WWW-Authenticate: Mock realm=server\r\n"
10641 "Content-Type: text/html; charset=iso-8859-1\r\n"
10642 "Content-Length: 14\r\n\r\n"
10643 "Unauthorized\r\n");
10644 const MockRead kSuccess(
10645 "HTTP/1.1 200 OK\r\n"
10646 "Content-Type: text/html; charset=iso-8859-1\r\n"
10647 "Content-Length: 3\r\n\r\n"
10648 "Yes");
10649
10650 MockWrite writes[] = {
10651 // First round
10652 kGet,
10653 // Second round
10654 kGetAuth,
10655 // Third round
10656 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010657 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010658 kGetAuth,
10659 // Competing request
10660 kGet,
[email protected]c871bce92010-07-15 21:51:1410661 };
10662 MockRead reads[] = {
10663 // First round
10664 kServerChallenge,
10665 // Second round
10666 kServerChallenge,
10667 // Third round
[email protected]eca50e122010-09-11 14:03:3010668 kServerChallenge,
10669 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410670 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010671 // Competing response
10672 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410673 };
10674 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10675 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710676 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410677
thestig9d3bb0c2015-01-24 00:49:5110678 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010679
10680 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410681 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110682 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410683 if (rv == ERR_IO_PENDING)
10684 rv = callback.WaitForResult();
10685 EXPECT_EQ(OK, rv);
10686 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010687 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410688 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810689 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410690
[email protected]7ef4cbbb2011-02-06 11:19:1010691 // In between rounds, another request comes in for the same domain.
10692 // It should not be able to grab the TCP socket that trans has already
10693 // claimed.
10694 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010695 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110696 TestCompletionCallback callback_compete;
10697 rv = trans_compete->Start(
10698 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010699 EXPECT_EQ(ERR_IO_PENDING, rv);
10700 // callback_compete.WaitForResult at this point would stall forever,
10701 // since the HttpNetworkTransaction does not release the request back to
10702 // the pool until after authentication completes.
10703
10704 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410705 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110706 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410707 if (rv == ERR_IO_PENDING)
10708 rv = callback.WaitForResult();
10709 EXPECT_EQ(OK, rv);
10710 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010711 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410712 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810713 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410714
[email protected]7ef4cbbb2011-02-06 11:19:1010715 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410716 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110717 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410718 if (rv == ERR_IO_PENDING)
10719 rv = callback.WaitForResult();
10720 EXPECT_EQ(OK, rv);
10721 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010722 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410723 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810724 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010725
[email protected]7ef4cbbb2011-02-06 11:19:1010726 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010727 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110728 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010729 if (rv == ERR_IO_PENDING)
10730 rv = callback.WaitForResult();
10731 EXPECT_EQ(OK, rv);
10732 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010733 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010734 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810735 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010736
10737 // Read the body since the fourth round was successful. This will also
10738 // release the socket back to the pool.
10739 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010740 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010741 if (rv == ERR_IO_PENDING)
10742 rv = callback.WaitForResult();
10743 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010744 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010745 EXPECT_EQ(0, rv);
10746 // There are still 0 idle sockets, since the trans_compete transaction
10747 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810748 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010749
10750 // The competing request can now finish. Wait for the headers and then
10751 // read the body.
10752 rv = callback_compete.WaitForResult();
10753 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010754 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010755 if (rv == ERR_IO_PENDING)
10756 rv = callback.WaitForResult();
10757 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010758 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010759 EXPECT_EQ(0, rv);
10760
10761 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810762 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410763}
10764
[email protected]65041fa2010-05-21 06:56:5310765// This tests the case that a request is issued via http instead of spdy after
10766// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210767TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bnc55ff9da2015-08-19 18:42:3510768 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310769 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610770 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310771 session_deps_.next_protos = next_protos;
10772
[email protected]65041fa2010-05-21 06:56:5310773 HttpRequestInfo request;
10774 request.method = "GET";
bncce36dca22015-04-21 22:11:2310775 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310776 request.load_flags = 0;
10777
10778 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310779 MockWrite(
10780 "GET / HTTP/1.1\r\n"
10781 "Host: www.example.org\r\n"
10782 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310783 };
10784
[email protected]8a0fc822013-06-27 20:52:4310785 std::string alternate_protocol_http_header =
10786 GetAlternateProtocolHttpHeader();
10787
[email protected]65041fa2010-05-21 06:56:5310788 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210789 MockRead("HTTP/1.1 200 OK\r\n"),
10790 MockRead(alternate_protocol_http_header.c_str()),
10791 MockRead("\r\n"),
10792 MockRead("hello world"),
10793 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310794 };
10795
[email protected]8ddf8322012-02-23 18:08:0610796 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810797 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310798
[email protected]bb88e1d32013-05-03 23:11:0710799 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310800
10801 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10802 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710803 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310804
[email protected]49639fa2011-12-20 23:22:4110805 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310806
[email protected]bb88e1d32013-05-03 23:11:0710807 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610808 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010809 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310810
[email protected]49639fa2011-12-20 23:22:4110811 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310812
10813 EXPECT_EQ(ERR_IO_PENDING, rv);
10814 EXPECT_EQ(OK, callback.WaitForResult());
10815
10816 const HttpResponseInfo* response = trans->GetResponseInfo();
10817 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010818 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310819 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10820
10821 std::string response_data;
10822 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10823 EXPECT_EQ("hello world", response_data);
10824
10825 EXPECT_FALSE(response->was_fetched_via_spdy);
10826 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310827}
[email protected]26ef6582010-06-24 02:30:4710828
bnc55ff9da2015-08-19 18:42:3510829// Simulate the SSL handshake completing with an NPN negotiation followed by an
10830// immediate server closing of the socket.
10831// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0210832TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bnc55ff9da2015-08-19 18:42:3510833 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310834 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710835
10836 HttpRequestInfo request;
10837 request.method = "GET";
bncce36dca22015-04-21 22:11:2310838 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710839 request.load_flags = 0;
10840
[email protected]8ddf8322012-02-23 18:08:0610841 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210842 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710843 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710844
[email protected]cdf8f7e72013-05-23 10:56:4610845 scoped_ptr<SpdyFrame> req(
10846 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310847 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710848
10849 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610850 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710851 };
10852
rch8e6c6c42015-05-01 14:05:1310853 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10854 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710855 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710856
[email protected]49639fa2011-12-20 23:22:4110857 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710858
[email protected]bb88e1d32013-05-03 23:11:0710859 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610860 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010861 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710862
[email protected]49639fa2011-12-20 23:22:4110863 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710864 EXPECT_EQ(ERR_IO_PENDING, rv);
10865 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710866}
[email protected]65d34382010-07-01 18:12:2610867
[email protected]795cbf82013-07-22 09:37:2710868// A subclass of HttpAuthHandlerMock that records the request URL when
10869// it gets it. This is needed since the auth handler may get destroyed
10870// before we get a chance to query it.
10871class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10872 public:
10873 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10874
dchengb03027d2014-10-21 12:00:2010875 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710876
10877 protected:
dchengb03027d2014-10-21 12:00:2010878 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10879 const HttpRequestInfo* request,
10880 const CompletionCallback& callback,
10881 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710882 *url_ = request->url;
10883 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10884 credentials, request, callback, auth_token);
10885 }
10886
10887 private:
10888 GURL* url_;
10889};
10890
bnc55ff9da2015-08-19 18:42:3510891// This test ensures that the URL passed into the proxy is upgraded to https
10892// when doing an Alternate Protocol upgrade.
[email protected]23e482282013-06-14 16:08:0210893TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
bnc55ff9da2015-08-19 18:42:3510894 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310895 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010896
[email protected]bb88e1d32013-05-03 23:11:0710897 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010898 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110899 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710900 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710901 GURL request_url;
10902 {
10903 HttpAuthHandlerMock::Factory* auth_factory =
10904 new HttpAuthHandlerMock::Factory();
10905 UrlRecordingHttpAuthHandlerMock* auth_handler =
10906 new UrlRecordingHttpAuthHandlerMock(&request_url);
10907 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10908 auth_factory->set_do_init_from_challenge(true);
10909 session_deps_.http_auth_handler_factory.reset(auth_factory);
10910 }
[email protected]f45c1ee2010-08-03 00:54:3010911
10912 HttpRequestInfo request;
10913 request.method = "GET";
bncce36dca22015-04-21 22:11:2310914 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3010915 request.load_flags = 0;
10916
10917 // First round goes unauthenticated through the proxy.
10918 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2310919 MockWrite(
10920 "GET http://www.example.org/ HTTP/1.1\r\n"
10921 "Host: www.example.org\r\n"
10922 "Proxy-Connection: keep-alive\r\n"
10923 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010924 };
10925 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610926 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810927 MockRead("HTTP/1.1 200 OK\r\n"),
10928 MockRead("Alternate-Protocol: 443:"),
10929 MockRead(GetAlternateProtocolFromParam()),
10930 MockRead("\r\n"),
10931 MockRead("Proxy-Connection: close\r\n"),
10932 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010933 };
10934 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10935 data_writes_1, arraysize(data_writes_1));
10936
bncce36dca22015-04-21 22:11:2310937 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3010938 // Alternate-Protocol announcement in the first round. It fails due
10939 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2310940 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5910941 // Proxy-Authorization headers. There is then a SPDY request round.
10942 //
[email protected]fe3b7dc2012-02-03 19:52:0910943 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10944 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10945 // does a Disconnect and Connect on the same socket, rather than trying
10946 // to obtain a new one.
10947 //
[email protected]394816e92010-08-03 07:38:5910948 // NOTE: Originally, the proxy response to the second CONNECT request
10949 // simply returned another 407 so the unit test could skip the SSL connection
10950 // establishment and SPDY framing issues. Alas, the
10951 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010952 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910953
[email protected]cdf8f7e72013-05-23 10:56:4610954 scoped_ptr<SpdyFrame> req(
10955 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210956 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10957 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010958
[email protected]394816e92010-08-03 07:38:5910959 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2310960 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310961 MockWrite(ASYNC, 0,
10962 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10963 "Host: www.example.org\r\n"
10964 "Proxy-Connection: keep-alive\r\n"
10965 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910966
bncce36dca22015-04-21 22:11:2310967 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310968 MockWrite(ASYNC, 2,
10969 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10970 "Host: www.example.org\r\n"
10971 "Proxy-Connection: keep-alive\r\n"
10972 "Proxy-Authorization: auth_token\r\n"
10973 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010974
bncce36dca22015-04-21 22:11:2310975 // SPDY request
rch8e6c6c42015-05-01 14:05:1310976 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3010977 };
[email protected]394816e92010-08-03 07:38:5910978 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1310979 // First connection attempt fails
mmenkee0b5c882015-08-26 20:29:1110980 MockRead(ASYNC, 1,
10981 "HTTP/1.1 407 Unauthorized\r\n"
10982 "Proxy-Authenticate: Mock\r\n"
10983 "Content-Length: 0\r\n"
10984 "Proxy-Connection: keep-alive\r\n"
10985 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910986
rch8e6c6c42015-05-01 14:05:1310987 // Second connection attempt passes
mmenkee0b5c882015-08-26 20:29:1110988 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5910989
rch8e6c6c42015-05-01 14:05:1310990 // SPDY response
mmenkee0b5c882015-08-26 20:29:1110991 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1310992 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5910993 };
rch8e6c6c42015-05-01 14:05:1310994 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
10995 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010996
[email protected]8ddf8322012-02-23 18:08:0610997 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210998 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310999 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11000 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3011001
[email protected]d973e99a2012-02-17 21:02:3611002 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511003 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11004 NULL, 0, NULL, 0);
11005 hanging_non_alternate_protocol_socket.set_connect_data(
11006 never_finishing_connect);
11007
[email protected]bb88e1d32013-05-03 23:11:0711008 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
11009 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
11010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11011 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511012 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0711013 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3011014
11015 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4111016 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3611017 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5011018 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111019 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011020 EXPECT_EQ(ERR_IO_PENDING, rv);
11021 EXPECT_EQ(OK, callback_1.WaitForResult());
11022
11023 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4111024 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3611025 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5011026 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111027 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011028 EXPECT_EQ(ERR_IO_PENDING, rv);
11029 EXPECT_EQ(OK, callback_2.WaitForResult());
11030 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011031 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3011032 ASSERT_FALSE(response->auth_challenge.get() == NULL);
11033
11034 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4111035 TestCompletionCallback callback_3;
11036 rv = trans_2->RestartWithAuth(
11037 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3011038 EXPECT_EQ(ERR_IO_PENDING, rv);
11039 EXPECT_EQ(OK, callback_3.WaitForResult());
11040
11041 // After all that work, these two lines (or actually, just the scheme) are
11042 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3011043 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2311044 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3011045
[email protected]029c83b62013-01-24 05:28:2011046 LoadTimingInfo load_timing_info;
11047 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
11048 TestLoadTimingNotReusedWithPac(load_timing_info,
11049 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3811050}
11051
11052// Test that if we cancel the transaction as the connection is completing, that
11053// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0211054TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3811055 // Setup everything about the connection to complete synchronously, so that
11056 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
11057 // for is the callback from the HttpStreamRequest.
11058 // Then cancel the transaction.
11059 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3611060 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3811061 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611062 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
11063 MockRead(SYNCHRONOUS, "hello world"),
11064 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3811065 };
11066
[email protected]8e6441ca2010-08-19 05:56:3811067 HttpRequestInfo request;
11068 request.method = "GET";
bncce36dca22015-04-21 22:11:2311069 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3811070 request.load_flags = 0;
11071
[email protected]bb88e1d32013-05-03 23:11:0711072 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0711073 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2711074 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111075 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2711076
[email protected]8e6441ca2010-08-19 05:56:3811077 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11078 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711079 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3811080
[email protected]49639fa2011-12-20 23:22:4111081 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3811082
vishal.b62985ca92015-04-17 08:45:5111083 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4111084 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3811085 EXPECT_EQ(ERR_IO_PENDING, rv);
11086 trans.reset(); // Cancel the transaction here.
11087
[email protected]2da659e2013-05-23 20:51:3411088 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3011089}
11090
[email protected]ecab6e052014-05-16 14:58:1211091// Test that if a transaction is cancelled after receiving the headers, the
11092// stream is drained properly and added back to the socket pool. The main
11093// purpose of this test is to make sure that an HttpStreamParser can be read
11094// from after the HttpNetworkTransaction and the objects it owns have been
11095// deleted.
11096// See http://crbug.com/368418
11097TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
11098 MockRead data_reads[] = {
11099 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
11100 MockRead(ASYNC, "Content-Length: 2\r\n"),
11101 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
11102 MockRead(ASYNC, "1"),
11103 // 2 async reads are necessary to trigger a ReadResponseBody call after the
11104 // HttpNetworkTransaction has been deleted.
11105 MockRead(ASYNC, "2"),
11106 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
11107 };
11108 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11109 session_deps_.socket_factory->AddSocketDataProvider(&data);
11110
11111 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11112
11113 {
11114 HttpRequestInfo request;
11115 request.method = "GET";
bncce36dca22015-04-21 22:11:2311116 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1211117 request.load_flags = 0;
11118
dcheng48459ac22014-08-26 00:46:4111119 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1211120 TestCompletionCallback callback;
11121
11122 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
11123 EXPECT_EQ(ERR_IO_PENDING, rv);
11124 callback.WaitForResult();
11125
11126 const HttpResponseInfo* response = trans.GetResponseInfo();
11127 ASSERT_TRUE(response != NULL);
11128 EXPECT_TRUE(response->headers.get() != NULL);
11129 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11130
11131 // The transaction and HttpRequestInfo are deleted.
11132 }
11133
11134 // Let the HttpResponseBodyDrainer drain the socket.
11135 base::MessageLoop::current()->RunUntilIdle();
11136
11137 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4111138 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1211139}
11140
[email protected]76a505b2010-08-25 06:23:0011141// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211142TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0711143 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2011144 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5111145 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711146 session_deps_.net_log = log.bound().net_log();
11147 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011148
[email protected]76a505b2010-08-25 06:23:0011149 HttpRequestInfo request;
11150 request.method = "GET";
bncce36dca22015-04-21 22:11:2311151 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011152
11153 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311154 MockWrite(
11155 "GET http://www.example.org/ HTTP/1.1\r\n"
11156 "Host: www.example.org\r\n"
11157 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011158 };
11159
11160 MockRead data_reads1[] = {
11161 MockRead("HTTP/1.1 200 OK\r\n"),
11162 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11163 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611164 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011165 };
11166
11167 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11168 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711169 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0011170
[email protected]49639fa2011-12-20 23:22:4111171 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011172
[email protected]262eec82013-03-19 21:01:3611173 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011174 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2711175 BeforeProxyHeadersSentHandler proxy_headers_handler;
11176 trans->SetBeforeProxyHeadersSentCallback(
11177 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
11178 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5011179
[email protected]49639fa2011-12-20 23:22:4111180 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011181 EXPECT_EQ(ERR_IO_PENDING, rv);
11182
11183 rv = callback1.WaitForResult();
11184 EXPECT_EQ(OK, rv);
11185
11186 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011187 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011188
11189 EXPECT_TRUE(response->headers->IsKeepAlive());
11190 EXPECT_EQ(200, response->headers->response_code());
11191 EXPECT_EQ(100, response->headers->GetContentLength());
11192 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511193 EXPECT_TRUE(
11194 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2711195 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
11196 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0011197 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2011198
11199 LoadTimingInfo load_timing_info;
11200 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11201 TestLoadTimingNotReusedWithPac(load_timing_info,
11202 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0011203}
11204
11205// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211206TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0711207 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2011208 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5111209 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711210 session_deps_.net_log = log.bound().net_log();
11211 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011212
[email protected]76a505b2010-08-25 06:23:0011213 HttpRequestInfo request;
11214 request.method = "GET";
bncce36dca22015-04-21 22:11:2311215 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011216
11217 // Since we have proxy, should try to establish tunnel.
11218 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311219 MockWrite(
11220 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11221 "Host: www.example.org\r\n"
11222 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011223
bncce36dca22015-04-21 22:11:2311224 MockWrite(
11225 "GET / HTTP/1.1\r\n"
11226 "Host: www.example.org\r\n"
11227 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011228 };
11229
11230 MockRead data_reads1[] = {
11231 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
11232
11233 MockRead("HTTP/1.1 200 OK\r\n"),
11234 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11235 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611236 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011237 };
11238
11239 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11240 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711241 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611242 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711243 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011244
[email protected]49639fa2011-12-20 23:22:4111245 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011246
[email protected]262eec82013-03-19 21:01:3611247 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011248 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011249
[email protected]49639fa2011-12-20 23:22:4111250 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011251 EXPECT_EQ(ERR_IO_PENDING, rv);
11252
11253 rv = callback1.WaitForResult();
11254 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4611255 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011256 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011257 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011258 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011259 NetLog::PHASE_NONE);
11260 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011261 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011262 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11263 NetLog::PHASE_NONE);
11264
11265 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011266 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011267
11268 EXPECT_TRUE(response->headers->IsKeepAlive());
11269 EXPECT_EQ(200, response->headers->response_code());
11270 EXPECT_EQ(100, response->headers->GetContentLength());
11271 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11272 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511273 EXPECT_TRUE(
11274 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2011275
11276 LoadTimingInfo load_timing_info;
11277 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11278 TestLoadTimingNotReusedWithPac(load_timing_info,
11279 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0011280}
11281
11282// Test a basic HTTPS GET request through a proxy, but the server hangs up
11283// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0211284TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0711285 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5111286 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711287 session_deps_.net_log = log.bound().net_log();
11288 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011289
[email protected]76a505b2010-08-25 06:23:0011290 HttpRequestInfo request;
11291 request.method = "GET";
bncce36dca22015-04-21 22:11:2311292 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011293
11294 // Since we have proxy, should try to establish tunnel.
11295 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311296 MockWrite(
11297 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11298 "Host: www.example.org\r\n"
11299 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011300
bncce36dca22015-04-21 22:11:2311301 MockWrite(
11302 "GET / HTTP/1.1\r\n"
11303 "Host: www.example.org\r\n"
11304 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011305 };
11306
11307 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0611308 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0011309 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611310 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0011311 };
11312
11313 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11314 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711315 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611316 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711317 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011318
[email protected]49639fa2011-12-20 23:22:4111319 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011320
[email protected]262eec82013-03-19 21:01:3611321 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011322 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011323
[email protected]49639fa2011-12-20 23:22:4111324 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011325 EXPECT_EQ(ERR_IO_PENDING, rv);
11326
11327 rv = callback1.WaitForResult();
11328 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4611329 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011330 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011331 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011332 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011333 NetLog::PHASE_NONE);
11334 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011335 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011336 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11337 NetLog::PHASE_NONE);
11338}
11339
[email protected]749eefa82010-09-13 22:14:0311340// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0211341TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4611342 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2311343 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1311344 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0311345
[email protected]23e482282013-06-14 16:08:0211346 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11347 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0311348 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311349 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0311350 };
11351
rch8e6c6c42015-05-01 14:05:1311352 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11353 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711354 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0311355
[email protected]8ddf8322012-02-23 18:08:0611356 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211357 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711358 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0311359
[email protected]bb88e1d32013-05-03 23:11:0711360 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0311361
11362 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2311363 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011364 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311365 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711366 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2611367 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311368
11369 HttpRequestInfo request;
11370 request.method = "GET";
bncce36dca22015-04-21 22:11:2311371 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0311372 request.load_flags = 0;
11373
11374 // This is the important line that marks this as a preconnect.
11375 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
11376
[email protected]262eec82013-03-19 21:01:3611377 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011378 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0311379
[email protected]41d64e82013-07-03 22:44:2611380 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4111381 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311382 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111383 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0311384}
11385
[email protected]73b8dd222010-11-11 19:55:2411386// Given a net error, cause that error to be returned from the first Write()
11387// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0211388void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0711389 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2911390 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711391 request_info.url = GURL("https://www.example.com/");
11392 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911393 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711394
[email protected]8ddf8322012-02-23 18:08:0611395 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2911396 MockWrite data_writes[] = {
11397 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2411398 };
ttuttle859dc7a2015-04-23 19:42:2911399 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711400 session_deps_.socket_factory->AddSocketDataProvider(&data);
11401 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2411402
[email protected]bb88e1d32013-05-03 23:11:0711403 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611404 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2411406
[email protected]49639fa2011-12-20 23:22:4111407 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911408 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11409 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2411410 rv = callback.WaitForResult();
11411 ASSERT_EQ(error, rv);
11412}
11413
[email protected]23e482282013-06-14 16:08:0211414TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411415 // Just check a grab bag of cert errors.
11416 static const int kErrors[] = {
11417 ERR_CERT_COMMON_NAME_INVALID,
11418 ERR_CERT_AUTHORITY_INVALID,
11419 ERR_CERT_DATE_INVALID,
11420 };
11421 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611422 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11423 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411424 }
11425}
11426
[email protected]bd0b6772011-01-11 19:59:3011427// Ensure that a client certificate is removed from the SSL client auth
11428// cache when:
11429// 1) No proxy is involved.
11430// 2) TLS False Start is disabled.
11431// 3) The initial TLS handshake requests a client certificate.
11432// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211433TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311434 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911435 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711436 request_info.url = GURL("https://www.example.com/");
11437 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911438 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711439
[email protected]bd0b6772011-01-11 19:59:3011440 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111441 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011442
11443 // [ssl_]data1 contains the data for the first SSL handshake. When a
11444 // CertificateRequest is received for the first time, the handshake will
11445 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911446 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011447 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911449 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711450 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011451
11452 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11453 // False Start is not being used, the result of the SSL handshake will be
11454 // returned as part of the SSLClientSocket::Connect() call. This test
11455 // matches the result of a server sending a handshake_failure alert,
11456 // rather than a Finished message, because it requires a client
11457 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911458 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011459 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711460 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911461 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711462 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011463
11464 // [ssl_]data3 contains the data for the third SSL handshake. When a
11465 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211466 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
11467 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011468 // of the HttpNetworkTransaction. Because this test failure is due to
11469 // requiring a client certificate, this fallback handshake should also
11470 // fail.
ttuttle859dc7a2015-04-23 19:42:2911471 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011472 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711473 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911474 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711475 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011476
[email protected]80c75f682012-05-26 16:22:1711477 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
11478 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211479 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
11480 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1711481 // of the HttpNetworkTransaction. Because this test failure is due to
11482 // requiring a client certificate, this fallback handshake should also
11483 // fail.
ttuttle859dc7a2015-04-23 19:42:2911484 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711485 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711486 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911487 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711488 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711489
[email protected]bb88e1d32013-05-03 23:11:0711490 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611491 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011492 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011493
[email protected]bd0b6772011-01-11 19:59:3011494 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111495 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911496 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11497 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011498
11499 // Complete the SSL handshake, which should abort due to requiring a
11500 // client certificate.
11501 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911502 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011503
11504 // Indicate that no certificate should be supplied. From the perspective
11505 // of SSLClientCertCache, NULL is just as meaningful as a real
11506 // certificate, so this is the same as supply a
11507 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111508 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911509 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011510
11511 // Ensure the certificate was added to the client auth cache before
11512 // allowing the connection to continue restarting.
11513 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111514 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11515 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011516 ASSERT_EQ(NULL, client_cert.get());
11517
11518 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711519 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11520 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011521 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911522 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011523
11524 // Ensure that the client certificate is removed from the cache on a
11525 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111526 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11527 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011528}
11529
11530// Ensure that a client certificate is removed from the SSL client auth
11531// cache when:
11532// 1) No proxy is involved.
11533// 2) TLS False Start is enabled.
11534// 3) The initial TLS handshake requests a client certificate.
11535// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211536TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311537 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911538 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711539 request_info.url = GURL("https://www.example.com/");
11540 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911541 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711542
[email protected]bd0b6772011-01-11 19:59:3011543 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111544 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011545
11546 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11547 // return successfully after reading up to the peer's Certificate message.
11548 // This is to allow the caller to call SSLClientSocket::Write(), which can
11549 // enqueue application data to be sent in the same packet as the
11550 // ChangeCipherSpec and Finished messages.
11551 // The actual handshake will be finished when SSLClientSocket::Read() is
11552 // called, which expects to process the peer's ChangeCipherSpec and
11553 // Finished messages. If there was an error negotiating with the peer,
11554 // such as due to the peer requiring a client certificate when none was
11555 // supplied, the alert sent by the peer won't be processed until Read() is
11556 // called.
11557
11558 // Like the non-False Start case, when a client certificate is requested by
11559 // the peer, the handshake is aborted during the Connect() call.
11560 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911561 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011562 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711563 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911564 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711565 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011566
11567 // When a client certificate is supplied, Connect() will not be aborted
11568 // when the peer requests the certificate. Instead, the handshake will
11569 // artificially succeed, allowing the caller to write the HTTP request to
11570 // the socket. The handshake messages are not processed until Read() is
11571 // called, which then detects that the handshake was aborted, due to the
11572 // peer sending a handshake_failure because it requires a client
11573 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911574 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011575 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711576 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911577 MockRead data2_reads[] = {
11578 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011579 };
ttuttle859dc7a2015-04-23 19:42:2911580 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711581 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011582
11583 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711584 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11585 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911586 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011587 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711588 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911589 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711590 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011591
[email protected]80c75f682012-05-26 16:22:1711592 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11593 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911594 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711595 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711596 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911597 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711598 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711599
[email protected]7799de12013-05-30 05:52:5111600 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911601 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111602 ssl_data5.cert_request_info = cert_request.get();
11603 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911604 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111605 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11606
[email protected]bb88e1d32013-05-03 23:11:0711607 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611608 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011610
[email protected]bd0b6772011-01-11 19:59:3011611 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111612 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911613 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11614 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011615
11616 // Complete the SSL handshake, which should abort due to requiring a
11617 // client certificate.
11618 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911619 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011620
11621 // Indicate that no certificate should be supplied. From the perspective
11622 // of SSLClientCertCache, NULL is just as meaningful as a real
11623 // certificate, so this is the same as supply a
11624 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111625 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911626 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011627
11628 // Ensure the certificate was added to the client auth cache before
11629 // allowing the connection to continue restarting.
11630 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111631 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11632 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011633 ASSERT_EQ(NULL, client_cert.get());
11634
[email protected]bd0b6772011-01-11 19:59:3011635 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711636 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11637 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011638 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911639 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011640
11641 // Ensure that the client certificate is removed from the cache on a
11642 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111643 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11644 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011645}
11646
[email protected]8c405132011-01-11 22:03:1811647// Ensure that a client certificate is removed from the SSL client auth
11648// cache when:
11649// 1) An HTTPS proxy is involved.
11650// 3) The HTTPS proxy requests a client certificate.
11651// 4) The client supplies an invalid/unacceptable certificate for the
11652// proxy.
11653// The test is repeated twice, first for connecting to an HTTPS endpoint,
11654// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211655TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711656 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811657 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:5111658 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711659 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811660
11661 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111662 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811663
11664 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11665 // [ssl_]data[1-3]. Rather than represending the endpoint
11666 // (www.example.com:443), they represent failures with the HTTPS proxy
11667 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911668 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811669 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711670 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911671 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711672 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811673
ttuttle859dc7a2015-04-23 19:42:2911674 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811675 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711676 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911677 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711678 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811679
[email protected]80c75f682012-05-26 16:22:1711680 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11681#if 0
ttuttle859dc7a2015-04-23 19:42:2911682 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811683 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711684 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911685 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711686 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711687#endif
[email protected]8c405132011-01-11 22:03:1811688
ttuttle859dc7a2015-04-23 19:42:2911689 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811690 requests[0].url = GURL("https://www.example.com/");
11691 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911692 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811693
11694 requests[1].url = GURL("http://www.example.com/");
11695 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911696 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811697
11698 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711699 session_deps_.socket_factory->ResetNextMockIndexes();
11700 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811701 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011702 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811703
11704 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111705 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911706 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11707 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811708
11709 // Complete the SSL handshake, which should abort due to requiring a
11710 // client certificate.
11711 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911712 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811713
11714 // Indicate that no certificate should be supplied. From the perspective
11715 // of SSLClientCertCache, NULL is just as meaningful as a real
11716 // certificate, so this is the same as supply a
11717 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111718 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911719 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811720
11721 // Ensure the certificate was added to the client auth cache before
11722 // allowing the connection to continue restarting.
11723 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111724 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11725 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811726 ASSERT_EQ(NULL, client_cert.get());
11727 // Ensure the certificate was NOT cached for the endpoint. This only
11728 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111729 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11730 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811731
11732 // Restart the handshake. This will consume ssl_data2, which fails, and
11733 // then consume ssl_data3, which should also fail. The result code is
11734 // checked against what ssl_data3 should return.
11735 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911736 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811737
11738 // Now that the new handshake has failed, ensure that the client
11739 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111740 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11741 HostPortPair("proxy", 70), &client_cert));
11742 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11743 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811744 }
11745}
11746
mmenke5c642132015-06-02 16:05:1311747TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bnc55ff9da2015-08-19 18:42:3511748 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311749 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611750
11751 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711752 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11753 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611754 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11755 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611756
[email protected]8ddf8322012-02-23 18:08:0611757 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211758 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711759 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611760
[email protected]cdf8f7e72013-05-23 10:56:4611761 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311762 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611763 scoped_ptr<SpdyFrame> host2_req(
11764 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611765 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311766 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611767 };
[email protected]23e482282013-06-14 16:08:0211768 scoped_ptr<SpdyFrame> host1_resp(
11769 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11770 scoped_ptr<SpdyFrame> host1_resp_body(
11771 spdy_util_.ConstructSpdyBodyFrame(1, true));
11772 scoped_ptr<SpdyFrame> host2_resp(
11773 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11774 scoped_ptr<SpdyFrame> host2_resp_body(
11775 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611776 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311777 CreateMockRead(*host1_resp, 1),
11778 CreateMockRead(*host1_resp_body, 2),
11779 CreateMockRead(*host2_resp, 4),
11780 CreateMockRead(*host2_resp_body, 5),
11781 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611782 };
11783
[email protected]d2b5f092012-06-08 23:55:0211784 IPAddressNumber ip;
11785 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11786 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11787 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311788 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11789 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711790 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611791
[email protected]aa22b242011-11-16 18:58:2911792 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611793 HttpRequestInfo request1;
11794 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311795 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611796 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011797 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611798
[email protected]49639fa2011-12-20 23:22:4111799 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611800 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111801 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611802
11803 const HttpResponseInfo* response = trans1.GetResponseInfo();
11804 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011805 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611806 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11807
11808 std::string response_data;
11809 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11810 EXPECT_EQ("hello!", response_data);
11811
11812 // Preload www.gmail.com into HostCache.
11813 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011814 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611815 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011816 rv = session_deps_.host_resolver->Resolve(resolve_info,
11817 DEFAULT_PRIORITY,
11818 &ignored,
11819 callback.callback(),
11820 NULL,
11821 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711822 EXPECT_EQ(ERR_IO_PENDING, rv);
11823 rv = callback.WaitForResult();
11824 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611825
11826 HttpRequestInfo request2;
11827 request2.method = "GET";
11828 request2.url = GURL("https://www.gmail.com/");
11829 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011830 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611831
[email protected]49639fa2011-12-20 23:22:4111832 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611833 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111834 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611835
11836 response = trans2.GetResponseInfo();
11837 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011838 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611839 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11840 EXPECT_TRUE(response->was_fetched_via_spdy);
11841 EXPECT_TRUE(response->was_npn_negotiated);
11842 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11843 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611844}
11845
[email protected]23e482282013-06-14 16:08:0211846TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bnc55ff9da2015-08-19 18:42:3511847 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311848 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211849
11850 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711851 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11852 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211853 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11854 pool_peer.DisableDomainAuthenticationVerification();
11855
11856 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211857 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711858 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211859
[email protected]cdf8f7e72013-05-23 10:56:4611860 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311861 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611862 scoped_ptr<SpdyFrame> host2_req(
11863 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211864 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311865 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0211866 };
[email protected]23e482282013-06-14 16:08:0211867 scoped_ptr<SpdyFrame> host1_resp(
11868 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11869 scoped_ptr<SpdyFrame> host1_resp_body(
11870 spdy_util_.ConstructSpdyBodyFrame(1, true));
11871 scoped_ptr<SpdyFrame> host2_resp(
11872 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11873 scoped_ptr<SpdyFrame> host2_resp_body(
11874 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211875 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311876 CreateMockRead(*host1_resp, 1),
11877 CreateMockRead(*host1_resp_body, 2),
11878 CreateMockRead(*host2_resp, 4),
11879 CreateMockRead(*host2_resp_body, 5),
11880 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0211881 };
11882
11883 IPAddressNumber ip;
11884 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11885 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11886 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311887 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11888 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711889 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211890
11891 TestCompletionCallback callback;
11892 HttpRequestInfo request1;
11893 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311894 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0211895 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011896 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211897
11898 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11899 EXPECT_EQ(ERR_IO_PENDING, rv);
11900 EXPECT_EQ(OK, callback.WaitForResult());
11901
11902 const HttpResponseInfo* response = trans1.GetResponseInfo();
11903 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011904 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211905 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11906
11907 std::string response_data;
11908 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11909 EXPECT_EQ("hello!", response_data);
11910
11911 HttpRequestInfo request2;
11912 request2.method = "GET";
11913 request2.url = GURL("https://www.gmail.com/");
11914 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011915 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211916
11917 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11918 EXPECT_EQ(ERR_IO_PENDING, rv);
11919 EXPECT_EQ(OK, callback.WaitForResult());
11920
11921 response = trans2.GetResponseInfo();
11922 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011923 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211924 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11925 EXPECT_TRUE(response->was_fetched_via_spdy);
11926 EXPECT_TRUE(response->was_npn_negotiated);
11927 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11928 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211929}
11930
ttuttle859dc7a2015-04-23 19:42:2911931class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4611932 public:
11933 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11934 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011935 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611936
11937 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11938
11939 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011940 int Resolve(const RequestInfo& info,
11941 RequestPriority priority,
11942 AddressList* addresses,
11943 const CompletionCallback& callback,
11944 RequestHandle* out_req,
11945 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011946 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011947 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011948 }
11949
dchengb03027d2014-10-21 12:00:2011950 int ResolveFromCache(const RequestInfo& info,
11951 AddressList* addresses,
11952 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011953 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11954 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911955 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611956 return rv;
11957 }
11958
dchengb03027d2014-10-21 12:00:2011959 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611960 host_resolver_.CancelRequest(req);
11961 }
11962
[email protected]46da33be2011-07-19 21:58:0411963 MockCachingHostResolver* GetMockHostResolver() {
11964 return &host_resolver_;
11965 }
11966
[email protected]e3ceb682011-06-28 23:55:4611967 private:
11968 MockCachingHostResolver host_resolver_;
11969 const HostPortPair host_port_;
11970};
11971
mmenke5c642132015-06-02 16:05:1311972TEST_P(HttpNetworkTransactionTest,
11973 UseIPConnectionPoolingWithHostCacheExpiration) {
bnc55ff9da2015-08-19 18:42:3511974 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311975 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611976
11977 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611978 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411979 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711980 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611981 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711982 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611983 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11984 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611985
[email protected]8ddf8322012-02-23 18:08:0611986 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211987 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711988 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611989
[email protected]cdf8f7e72013-05-23 10:56:4611990 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311991 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611992 scoped_ptr<SpdyFrame> host2_req(
11993 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611994 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311995 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611996 };
[email protected]23e482282013-06-14 16:08:0211997 scoped_ptr<SpdyFrame> host1_resp(
11998 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11999 scoped_ptr<SpdyFrame> host1_resp_body(
12000 spdy_util_.ConstructSpdyBodyFrame(1, true));
12001 scoped_ptr<SpdyFrame> host2_resp(
12002 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12003 scoped_ptr<SpdyFrame> host2_resp_body(
12004 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612005 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312006 CreateMockRead(*host1_resp, 1),
12007 CreateMockRead(*host1_resp_body, 2),
12008 CreateMockRead(*host2_resp, 4),
12009 CreateMockRead(*host2_resp_body, 5),
12010 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612011 };
12012
[email protected]d2b5f092012-06-08 23:55:0212013 IPAddressNumber ip;
12014 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12015 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12016 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312017 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12018 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712019 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612020
[email protected]aa22b242011-11-16 18:58:2912021 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612022 HttpRequestInfo request1;
12023 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312024 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612025 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012026 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612027
[email protected]49639fa2011-12-20 23:22:4112028 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612029 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112030 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612031
12032 const HttpResponseInfo* response = trans1.GetResponseInfo();
12033 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012034 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612035 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12036
12037 std::string response_data;
12038 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12039 EXPECT_EQ("hello!", response_data);
12040
12041 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1012042 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4612043 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012044 rv = host_resolver.Resolve(resolve_info,
12045 DEFAULT_PRIORITY,
12046 &ignored,
12047 callback.callback(),
12048 NULL,
12049 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712050 EXPECT_EQ(ERR_IO_PENDING, rv);
12051 rv = callback.WaitForResult();
12052 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612053
12054 HttpRequestInfo request2;
12055 request2.method = "GET";
12056 request2.url = GURL("https://www.gmail.com/");
12057 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012058 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612059
[email protected]49639fa2011-12-20 23:22:4112060 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612061 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112062 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612063
12064 response = trans2.GetResponseInfo();
12065 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012066 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612067 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12068 EXPECT_TRUE(response->was_fetched_via_spdy);
12069 EXPECT_TRUE(response->was_npn_negotiated);
12070 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12071 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612072}
12073
[email protected]23e482282013-06-14 16:08:0212074TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2312075 const std::string https_url = "https://www.example.org:8080/";
12076 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412077
12078 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4612079 scoped_ptr<SpdyFrame> req1(
12080 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0412081
12082 MockWrite writes1[] = {
12083 CreateMockWrite(*req1, 0),
12084 };
12085
[email protected]23e482282013-06-14 16:08:0212086 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12087 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0412088 MockRead reads1[] = {
12089 CreateMockRead(*resp1, 1),
12090 CreateMockRead(*body1, 2),
12091 MockRead(ASYNC, ERR_IO_PENDING, 3)
12092 };
12093
rch8e6c6c42015-05-01 14:05:1312094 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
12095 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412096 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712097 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412098
12099 // HTTP GET for the HTTP URL
12100 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1312101 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3412102 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2312103 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3412104 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0412105 };
12106
12107 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1312108 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12109 MockRead(ASYNC, 2, "hello"),
12110 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0412111 };
12112
rch8e6c6c42015-05-01 14:05:1312113 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12114 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0412115
[email protected]8450d722012-07-02 19:14:0412116 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212117 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712118 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12119 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12120 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0412121
[email protected]bb88e1d32013-05-03 23:11:0712122 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412123
12124 // Start the first transaction to set up the SpdySession
12125 HttpRequestInfo request1;
12126 request1.method = "GET";
12127 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412128 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012129 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412130 TestCompletionCallback callback1;
12131 EXPECT_EQ(ERR_IO_PENDING,
12132 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412133 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412134
12135 EXPECT_EQ(OK, callback1.WaitForResult());
12136 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12137
12138 // Now, start the HTTP request
12139 HttpRequestInfo request2;
12140 request2.method = "GET";
12141 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412142 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012143 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412144 TestCompletionCallback callback2;
12145 EXPECT_EQ(ERR_IO_PENDING,
12146 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412147 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412148
12149 EXPECT_EQ(OK, callback2.WaitForResult());
12150 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12151}
12152
bnc1b0e36852015-04-28 15:32:5912153class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
12154 public:
12155 void Run(bool pooling, bool valid) {
12156 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
12157 443);
12158 HostPortPair alternative("www.example.org", 443);
12159
12160 base::FilePath certs_dir = GetTestCertsDirectory();
12161 scoped_refptr<X509Certificate> cert(
12162 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
12163 ASSERT_TRUE(cert.get());
12164 bool common_name_fallback_used;
12165 EXPECT_EQ(valid,
12166 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
12167 EXPECT_TRUE(
12168 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
12169 SSLSocketDataProvider ssl(ASYNC, OK);
12170 ssl.SetNextProto(GetParam());
12171 ssl.cert = cert;
12172 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12173
12174 // If pooling, then start a request to alternative first to create a
12175 // SpdySession.
12176 std::string url0 = "https://www.example.org:443";
12177 // Second request to origin, which has an alternative service, and could
12178 // open a connection to the alternative host or pool to the existing one.
12179 std::string url1("https://");
12180 url1.append(origin.host());
12181 url1.append(":443");
12182
12183 scoped_ptr<SpdyFrame> req0;
12184 scoped_ptr<SpdyFrame> req1;
12185 scoped_ptr<SpdyFrame> resp0;
12186 scoped_ptr<SpdyFrame> body0;
12187 scoped_ptr<SpdyFrame> resp1;
12188 scoped_ptr<SpdyFrame> body1;
12189 std::vector<MockWrite> writes;
12190 std::vector<MockRead> reads;
12191
12192 if (pooling) {
12193 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
12194 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
12195
12196 writes.push_back(CreateMockWrite(*req0, 0));
12197 writes.push_back(CreateMockWrite(*req1, 3));
12198
12199 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12200 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12201 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12202 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
12203
12204 reads.push_back(CreateMockRead(*resp0, 1));
12205 reads.push_back(CreateMockRead(*body0, 2));
12206 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
12207 reads.push_back(CreateMockRead(*resp1, 5));
12208 reads.push_back(CreateMockRead(*body1, 6));
12209 reads.push_back(MockRead(ASYNC, OK, 7));
12210 } else {
12211 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
12212
12213 writes.push_back(CreateMockWrite(*req1, 0));
12214
12215 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12216 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12217
12218 reads.push_back(CreateMockRead(*resp1, 1));
12219 reads.push_back(CreateMockRead(*body1, 2));
12220 reads.push_back(MockRead(ASYNC, OK, 3));
12221 }
12222
rch32320842015-05-16 15:57:0912223 SequencedSocketData data(vector_as_array(&reads), reads.size(),
12224 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5912225 session_deps_.socket_factory->AddSocketDataProvider(&data);
12226
12227 // Connection to the origin fails.
12228 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12229 StaticSocketDataProvider data_refused;
12230 data_refused.set_connect_data(mock_connect);
12231 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12232
bnc55ff9da2015-08-19 18:42:3512233 session_deps_.use_alternative_services = true;
bnc1b0e36852015-04-28 15:32:5912234 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12235 base::WeakPtr<HttpServerProperties> http_server_properties =
12236 session->http_server_properties();
12237 AlternativeService alternative_service(
12238 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212239 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc1b0e36852015-04-28 15:32:5912240 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212241 1.0, expiration);
bnc1b0e36852015-04-28 15:32:5912242
12243 // First request to alternative.
12244 if (pooling) {
12245 scoped_ptr<HttpTransaction> trans0(
12246 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12247 HttpRequestInfo request0;
12248 request0.method = "GET";
12249 request0.url = GURL(url0);
12250 request0.load_flags = 0;
12251 TestCompletionCallback callback0;
12252
12253 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
12254 EXPECT_EQ(ERR_IO_PENDING, rv);
12255 rv = callback0.WaitForResult();
12256 EXPECT_EQ(OK, rv);
12257 }
12258
12259 // Second request to origin.
12260 scoped_ptr<HttpTransaction> trans1(
12261 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12262 HttpRequestInfo request1;
12263 request1.method = "GET";
12264 request1.url = GURL(url1);
12265 request1.load_flags = 0;
12266 TestCompletionCallback callback1;
12267
12268 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12269 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0912270 base::MessageLoop::current()->RunUntilIdle();
12271 if (data.IsReadPaused()) {
12272 data.CompleteRead();
12273 }
bnc1b0e36852015-04-28 15:32:5912274 rv = callback1.WaitForResult();
12275 if (valid) {
12276 EXPECT_EQ(OK, rv);
12277 } else {
12278 if (pooling) {
12279 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12280 } else {
12281 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
12282 }
12283 }
12284 }
12285};
12286
12287INSTANTIATE_TEST_CASE_P(NextProto,
12288 AltSvcCertificateVerificationTest,
12289 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:4312290 kProtoHTTP2));
bnc1b0e36852015-04-28 15:32:5912291
12292// The alternative service host must exhibit a certificate that is valid for the
12293// origin host. Test that this is enforced when pooling to an existing
12294// connection.
12295TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
12296 Run(true, true);
12297}
12298
12299TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
12300 Run(true, false);
12301}
12302
12303// The alternative service host must exhibit a certificate that is valid for the
12304// origin host. Test that this is enforced when opening a new connection.
12305TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
12306 Run(false, true);
12307}
12308
12309TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
12310 Run(false, false);
12311}
12312
bnc5452e2a2015-05-08 16:27:4212313// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
12314// with the alternative server. That connection should not be used.
12315TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
12316 HostPortPair origin("origin.example.org", 443);
12317 HostPortPair alternative("alternative.example.org", 443);
12318
12319 // Negotiate HTTP/1.1 with alternative.example.org.
12320 SSLSocketDataProvider ssl(ASYNC, OK);
12321 ssl.SetNextProto(kProtoHTTP11);
12322 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12323
12324 // No data should be read from the alternative, because HTTP/1.1 is
12325 // negotiated.
12326 StaticSocketDataProvider data;
12327 session_deps_.socket_factory->AddSocketDataProvider(&data);
12328
12329 // This test documents that an alternate Job should not be used if HTTP/1.1 is
12330 // negotiated. In order to test this, a failed connection to the origin is
12331 // mocked. This way the request relies on the alternate Job.
12332 StaticSocketDataProvider data_refused;
12333 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12334 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12335
12336 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512337 session_deps_.use_alternative_services = true;
bnc5452e2a2015-05-08 16:27:4212338 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12339 base::WeakPtr<HttpServerProperties> http_server_properties =
12340 session->http_server_properties();
12341 AlternativeService alternative_service(
12342 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212343 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212344 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212345 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212346
12347 scoped_ptr<HttpTransaction> trans(
12348 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12349 HttpRequestInfo request;
12350 request.method = "GET";
12351 request.url = GURL("https://origin.example.org:443");
12352 request.load_flags = 0;
12353 TestCompletionCallback callback;
12354
12355 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
12356 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
12357 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12358 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
12359}
12360
bnc40448a532015-05-11 19:13:1412361// A request to a server with an alternative service fires two Jobs: one to the
12362// origin, and an alternate one to the alternative server. If the former
12363// succeeds, the request should succeed, even if the latter fails because
12364// HTTP/1.1 is negotiated which is insufficient for alternative service.
12365TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
12366 HostPortPair origin("origin.example.org", 443);
12367 HostPortPair alternative("alternative.example.org", 443);
12368
12369 // Negotiate HTTP/1.1 with alternative.
12370 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
12371 alternative_ssl.SetNextProto(kProtoHTTP11);
12372 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
12373
12374 // No data should be read from the alternative, because HTTP/1.1 is
12375 // negotiated.
12376 StaticSocketDataProvider data;
12377 session_deps_.socket_factory->AddSocketDataProvider(&data);
12378
12379 // Negotiate HTTP/1.1 with origin.
12380 SSLSocketDataProvider origin_ssl(ASYNC, OK);
12381 origin_ssl.SetNextProto(kProtoHTTP11);
12382 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
12383
12384 MockWrite http_writes[] = {
12385 MockWrite(
12386 "GET / HTTP/1.1\r\n"
12387 "Host: origin.example.org\r\n"
12388 "Connection: keep-alive\r\n\r\n"),
12389 MockWrite(
12390 "GET /second HTTP/1.1\r\n"
12391 "Host: origin.example.org\r\n"
12392 "Connection: keep-alive\r\n\r\n"),
12393 };
12394
12395 MockRead http_reads[] = {
12396 MockRead("HTTP/1.1 200 OK\r\n"),
12397 MockRead("Content-Type: text/html\r\n"),
12398 MockRead("Content-Length: 6\r\n\r\n"),
12399 MockRead("foobar"),
12400 MockRead("HTTP/1.1 200 OK\r\n"),
12401 MockRead("Content-Type: text/html\r\n"),
12402 MockRead("Content-Length: 7\r\n\r\n"),
12403 MockRead("another"),
12404 };
12405 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12406 http_writes, arraysize(http_writes));
12407 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12408
12409 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512410 session_deps_.use_alternative_services = true;
bnc40448a532015-05-11 19:13:1412411 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12412 base::WeakPtr<HttpServerProperties> http_server_properties =
12413 session->http_server_properties();
12414 AlternativeService alternative_service(
12415 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212416 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc40448a532015-05-11 19:13:1412417 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212418 1.0, expiration);
bnc40448a532015-05-11 19:13:1412419
12420 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
12421 HttpRequestInfo request1;
12422 request1.method = "GET";
12423 request1.url = GURL("https://origin.example.org:443");
12424 request1.load_flags = 0;
12425 TestCompletionCallback callback1;
12426
12427 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
12428 rv = callback1.GetResult(rv);
12429 EXPECT_EQ(OK, rv);
12430
12431 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
12432 ASSERT_TRUE(response1 != nullptr);
12433 ASSERT_TRUE(response1->headers.get() != nullptr);
12434 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12435
12436 std::string response_data1;
12437 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
12438 EXPECT_EQ("foobar", response_data1);
12439
12440 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
12441 // for alternative service.
12442 EXPECT_TRUE(
12443 http_server_properties->IsAlternativeServiceBroken(alternative_service));
12444
12445 // Since |alternative_service| is broken, a second transaction to origin
12446 // should not start an alternate Job. It should pool to existing connection
12447 // to origin.
12448 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
12449 HttpRequestInfo request2;
12450 request2.method = "GET";
12451 request2.url = GURL("https://origin.example.org:443/second");
12452 request2.load_flags = 0;
12453 TestCompletionCallback callback2;
12454
12455 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
12456 rv = callback2.GetResult(rv);
12457 EXPECT_EQ(OK, rv);
12458
12459 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
12460 ASSERT_TRUE(response2 != nullptr);
12461 ASSERT_TRUE(response2->headers.get() != nullptr);
12462 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
12463
12464 std::string response_data2;
12465 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
12466 EXPECT_EQ("another", response_data2);
12467}
12468
bnc5452e2a2015-05-08 16:27:4212469// Alternative service requires HTTP/2 (or SPDY), but there is already a
12470// HTTP/1.1 socket open to the alternative server. That socket should not be
12471// used.
12472TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12473 HostPortPair origin("origin.example.org", 443);
12474 HostPortPair alternative("alternative.example.org", 443);
12475 std::string origin_url = "https://origin.example.org:443";
12476 std::string alternative_url = "https://alternative.example.org:443";
12477
12478 // Negotiate HTTP/1.1 with alternative.example.org.
12479 SSLSocketDataProvider ssl(ASYNC, OK);
12480 ssl.SetNextProto(kProtoHTTP11);
12481 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12482
12483 // HTTP/1.1 data for |request1| and |request2|.
12484 MockWrite http_writes[] = {
12485 MockWrite(
12486 "GET / HTTP/1.1\r\n"
12487 "Host: alternative.example.org\r\n"
12488 "Connection: keep-alive\r\n\r\n"),
12489 MockWrite(
12490 "GET / HTTP/1.1\r\n"
12491 "Host: alternative.example.org\r\n"
12492 "Connection: keep-alive\r\n\r\n"),
12493 };
12494
12495 MockRead http_reads[] = {
12496 MockRead(
12497 "HTTP/1.1 200 OK\r\n"
12498 "Content-Type: text/html; charset=iso-8859-1\r\n"
12499 "Content-Length: 40\r\n\r\n"
12500 "first HTTP/1.1 response from alternative"),
12501 MockRead(
12502 "HTTP/1.1 200 OK\r\n"
12503 "Content-Type: text/html; charset=iso-8859-1\r\n"
12504 "Content-Length: 41\r\n\r\n"
12505 "second HTTP/1.1 response from alternative"),
12506 };
12507 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12508 http_writes, arraysize(http_writes));
12509 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12510
12511 // This test documents that an alternate Job should not pool to an already
12512 // existing HTTP/1.1 connection. In order to test this, a failed connection
12513 // to the origin is mocked. This way |request2| relies on the alternate Job.
12514 StaticSocketDataProvider data_refused;
12515 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12516 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12517
12518 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512519 session_deps_.use_alternative_services = true;
bnc5452e2a2015-05-08 16:27:4212520 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12521 base::WeakPtr<HttpServerProperties> http_server_properties =
12522 session->http_server_properties();
12523 AlternativeService alternative_service(
12524 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212525 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212526 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212527 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212528
12529 // First transaction to alternative to open an HTTP/1.1 socket.
12530 scoped_ptr<HttpTransaction> trans1(
12531 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12532 HttpRequestInfo request1;
12533 request1.method = "GET";
12534 request1.url = GURL(alternative_url);
12535 request1.load_flags = 0;
12536 TestCompletionCallback callback1;
12537
12538 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12539 EXPECT_EQ(OK, callback1.GetResult(rv));
12540 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12541 ASSERT_TRUE(response1);
12542 ASSERT_TRUE(response1->headers.get());
12543 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12544 EXPECT_TRUE(response1->was_npn_negotiated);
12545 EXPECT_FALSE(response1->was_fetched_via_spdy);
12546 std::string response_data1;
12547 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12548 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12549
12550 // Request for origin.example.org, which has an alternative service. This
12551 // will start two Jobs: the alternative looks for connections to pool to,
12552 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12553 // open other connections to alternative server. The Job to origin fails, so
12554 // this request fails.
12555 scoped_ptr<HttpTransaction> trans2(
12556 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12557 HttpRequestInfo request2;
12558 request2.method = "GET";
12559 request2.url = GURL(origin_url);
12560 request2.load_flags = 0;
12561 TestCompletionCallback callback2;
12562
12563 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12564 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12565
12566 // Another transaction to alternative. This is to test that the HTTP/1.1
12567 // socket is still open and in the pool.
12568 scoped_ptr<HttpTransaction> trans3(
12569 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12570 HttpRequestInfo request3;
12571 request3.method = "GET";
12572 request3.url = GURL(alternative_url);
12573 request3.load_flags = 0;
12574 TestCompletionCallback callback3;
12575
12576 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12577 EXPECT_EQ(OK, callback3.GetResult(rv));
12578 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12579 ASSERT_TRUE(response3);
12580 ASSERT_TRUE(response3->headers.get());
12581 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12582 EXPECT_TRUE(response3->was_npn_negotiated);
12583 EXPECT_FALSE(response3->was_fetched_via_spdy);
12584 std::string response_data3;
12585 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12586 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12587}
12588
[email protected]23e482282013-06-14 16:08:0212589TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2312590 const std::string https_url = "https://www.example.org:8080/";
12591 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412592
12593 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2312594 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3412595 scoped_ptr<SpdyFrame> connect(
12596 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4612597 scoped_ptr<SpdyFrame> req1(
12598 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0212599 scoped_ptr<SpdyFrame> wrapped_req1(
12600 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3912601
12602 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2912603 SpdyHeaderBlock req2_block;
12604 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3812605 req2_block[spdy_util_.GetPathKey()] = "/";
bncce36dca22015-04-21 22:11:2312606 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2912607 req2_block[spdy_util_.GetSchemeKey()] = "http";
12608 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3912609 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2912610 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0412611
12612 MockWrite writes1[] = {
12613 CreateMockWrite(*connect, 0),
12614 CreateMockWrite(*wrapped_req1, 2),
12615 CreateMockWrite(*req2, 5),
12616 };
12617
[email protected]23e482282013-06-14 16:08:0212618 scoped_ptr<SpdyFrame> conn_resp(
12619 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12620 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12621 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12622 scoped_ptr<SpdyFrame> wrapped_resp1(
12623 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12624 scoped_ptr<SpdyFrame> wrapped_body1(
12625 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12626 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12627 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412628 MockRead reads1[] = {
12629 CreateMockRead(*conn_resp, 1),
12630 CreateMockRead(*wrapped_resp1, 3),
12631 CreateMockRead(*wrapped_body1, 4),
12632 CreateMockRead(*resp2, 6),
12633 CreateMockRead(*body2, 7),
12634 MockRead(ASYNC, ERR_IO_PENDING, 8)
12635 };
12636
[email protected]dd54bd82012-07-19 23:44:5712637 DeterministicSocketData data1(reads1, arraysize(reads1),
12638 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412639 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712640 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412641
[email protected]bb88e1d32013-05-03 23:11:0712642 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2212643 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:5112644 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712645 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412646 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212647 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712648 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412649 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212650 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712651 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12652 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412653
12654 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712655 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412656
12657 // Start the first transaction to set up the SpdySession
12658 HttpRequestInfo request1;
12659 request1.method = "GET";
12660 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412661 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012662 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412663 TestCompletionCallback callback1;
12664 EXPECT_EQ(ERR_IO_PENDING,
12665 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412666 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712667 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412668
12669 EXPECT_EQ(OK, callback1.WaitForResult());
12670 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12671
[email protected]f6c63db52013-02-02 00:35:2212672 LoadTimingInfo load_timing_info1;
12673 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12674 TestLoadTimingNotReusedWithPac(load_timing_info1,
12675 CONNECT_TIMING_HAS_SSL_TIMES);
12676
[email protected]8450d722012-07-02 19:14:0412677 // Now, start the HTTP request
12678 HttpRequestInfo request2;
12679 request2.method = "GET";
12680 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412681 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012682 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412683 TestCompletionCallback callback2;
12684 EXPECT_EQ(ERR_IO_PENDING,
12685 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412686 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712687 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412688
12689 EXPECT_EQ(OK, callback2.WaitForResult());
12690 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212691
12692 LoadTimingInfo load_timing_info2;
12693 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12694 // The established SPDY sessions is considered reused by the HTTP request.
12695 TestLoadTimingReusedWithPac(load_timing_info2);
12696 // HTTP requests over a SPDY session should have a different connection
12697 // socket_log_id than requests over a tunnel.
12698 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412699}
12700
[email protected]2d88e7d2012-07-19 17:55:1712701// Test that in the case where we have a SPDY session to a SPDY proxy
12702// that we do not pool other origins that resolve to the same IP when
12703// the certificate does not match the new origin.
12704// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212705TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312706 const std::string url1 = "http://www.example.org/";
12707 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712708 const std::string ip_addr = "1.2.3.4";
12709
12710 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212711 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312712 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912713 scoped_ptr<SpdyFrame> req1(
12714 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712715
12716 MockWrite writes1[] = {
12717 CreateMockWrite(*req1, 0),
12718 };
12719
[email protected]23e482282013-06-14 16:08:0212720 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12721 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712722 MockRead reads1[] = {
bncb9e20fc62015-08-17 17:19:3712723 CreateMockRead(*resp1, 1),
12724 CreateMockRead(*body1, 2),
12725 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712726 };
12727
12728 scoped_ptr<DeterministicSocketData> data1(
12729 new DeterministicSocketData(reads1, arraysize(reads1),
12730 writes1, arraysize(writes1)));
12731 IPAddressNumber ip;
12732 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12733 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12734 MockConnect connect_data1(ASYNC, OK, peer_addr);
12735 data1->set_connect_data(connect_data1);
12736
12737 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612738 scoped_ptr<SpdyFrame> req2(
12739 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712740
12741 MockWrite writes2[] = {
12742 CreateMockWrite(*req2, 0),
12743 };
12744
[email protected]23e482282013-06-14 16:08:0212745 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12746 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712747 MockRead reads2[] = {
bncb9e20fc62015-08-17 17:19:3712748 CreateMockRead(*resp2, 1),
12749 CreateMockRead(*body2, 2),
12750 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712751 };
12752
12753 scoped_ptr<DeterministicSocketData> data2(
12754 new DeterministicSocketData(reads2, arraysize(reads2),
12755 writes2, arraysize(writes2)));
12756 MockConnect connect_data2(ASYNC, OK);
12757 data2->set_connect_data(connect_data2);
12758
12759 // Set up a proxy config that sends HTTP requests to a proxy, and
12760 // all others direct.
12761 ProxyConfig proxy_config;
12762 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712763 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:1312764 new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
[email protected]2d88e7d2012-07-19 17:55:1712765
bncce36dca22015-04-21 22:11:2312766 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12767 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712768 // Load a valid cert. Note, that this does not need to
12769 // be valid for proxy because the MockSSLClientSocket does
12770 // not actually verify it. But SpdySession will use this
12771 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312772 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12773 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712774 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12775 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12776 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712777
12778 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212779 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712780 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12781 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12782 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712783
[email protected]bb88e1d32013-05-03 23:11:0712784 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312785 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712786 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712787
12788 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712789 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712790
12791 // Start the first transaction to set up the SpdySession
12792 HttpRequestInfo request1;
12793 request1.method = "GET";
12794 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712795 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012796 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712797 TestCompletionCallback callback1;
12798 ASSERT_EQ(ERR_IO_PENDING,
12799 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12800 data1->RunFor(3);
12801
12802 ASSERT_TRUE(callback1.have_result());
12803 EXPECT_EQ(OK, callback1.WaitForResult());
12804 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12805
12806 // Now, start the HTTP request
12807 HttpRequestInfo request2;
12808 request2.method = "GET";
12809 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712810 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012811 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712812 TestCompletionCallback callback2;
12813 EXPECT_EQ(ERR_IO_PENDING,
12814 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412815 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712816 data2->RunFor(3);
12817
12818 ASSERT_TRUE(callback2.have_result());
12819 EXPECT_EQ(OK, callback2.WaitForResult());
12820 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12821}
12822
[email protected]85f97342013-04-17 06:12:2412823// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12824// error) in SPDY session, removes the socket from pool and closes the SPDY
12825// session. Verify that new url's from the same HttpNetworkSession (and a new
12826// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212827TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312828 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412829
12830 MockRead reads1[] = {
12831 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12832 };
12833
mmenke11eb5152015-06-09 14:50:5012834 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2412835
[email protected]cdf8f7e72013-05-23 10:56:4612836 scoped_ptr<SpdyFrame> req2(
12837 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412838 MockWrite writes2[] = {
12839 CreateMockWrite(*req2, 0),
12840 };
12841
[email protected]23e482282013-06-14 16:08:0212842 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12843 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412844 MockRead reads2[] = {
12845 CreateMockRead(*resp2, 1),
12846 CreateMockRead(*body2, 2),
12847 MockRead(ASYNC, OK, 3) // EOF
12848 };
12849
mmenke11eb5152015-06-09 14:50:5012850 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12851 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2412852
[email protected]85f97342013-04-17 06:12:2412853 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212854 ssl1.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012855 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12856 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2412857
12858 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212859 ssl2.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12861 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2412862
12863 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5012864 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412865
12866 // Start the first transaction to set up the SpdySession and verify that
12867 // connection was closed.
12868 HttpRequestInfo request1;
12869 request1.method = "GET";
12870 request1.url = GURL(https_url);
12871 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012872 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412873 TestCompletionCallback callback1;
12874 EXPECT_EQ(ERR_IO_PENDING,
12875 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412876 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12877
12878 // Now, start the second request and make sure it succeeds.
12879 HttpRequestInfo request2;
12880 request2.method = "GET";
12881 request2.url = GURL(https_url);
12882 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012883 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412884 TestCompletionCallback callback2;
12885 EXPECT_EQ(ERR_IO_PENDING,
12886 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412887
mmenke11eb5152015-06-09 14:50:5012888 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2412889 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12890}
12891
[email protected]23e482282013-06-14 16:08:0212892TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312893 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312894 ClientSocketPoolManager::set_max_sockets_per_group(
12895 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12896 ClientSocketPoolManager::set_max_sockets_per_pool(
12897 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12898
12899 // Use two different hosts with different IPs so they don't get pooled.
12900 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12901 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
12902 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12903
12904 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212905 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312906 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212907 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312908 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12909 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12910
[email protected]cdf8f7e72013-05-23 10:56:4612911 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312912 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12913 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1312914 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0312915 };
[email protected]23e482282013-06-14 16:08:0212916 scoped_ptr<SpdyFrame> host1_resp(
12917 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12918 scoped_ptr<SpdyFrame> host1_resp_body(
12919 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312920 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1312921 CreateMockRead(*host1_resp, 1),
12922 CreateMockRead(*host1_resp_body, 2),
12923 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312924 };
12925
rch8e6c6c42015-05-01 14:05:1312926 scoped_ptr<SequencedSocketData> spdy1_data(
12927 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
12928 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0312929 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12930
[email protected]cdf8f7e72013-05-23 10:56:4612931 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312932 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12933 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1312934 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0312935 };
[email protected]23e482282013-06-14 16:08:0212936 scoped_ptr<SpdyFrame> host2_resp(
12937 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12938 scoped_ptr<SpdyFrame> host2_resp_body(
12939 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312940 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1312941 CreateMockRead(*host2_resp, 1),
12942 CreateMockRead(*host2_resp_body, 2),
12943 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312944 };
12945
rch8e6c6c42015-05-01 14:05:1312946 scoped_ptr<SequencedSocketData> spdy2_data(
12947 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
12948 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0312949 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12950
12951 MockWrite http_write[] = {
12952 MockWrite("GET / HTTP/1.1\r\n"
12953 "Host: www.a.com\r\n"
12954 "Connection: keep-alive\r\n\r\n"),
12955 };
12956
12957 MockRead http_read[] = {
12958 MockRead("HTTP/1.1 200 OK\r\n"),
12959 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12960 MockRead("Content-Length: 6\r\n\r\n"),
12961 MockRead("hello!"),
12962 };
12963 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12964 http_write, arraysize(http_write));
12965 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12966
12967 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012968 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312969 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312970 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612971 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312972
12973 TestCompletionCallback callback;
12974 HttpRequestInfo request1;
12975 request1.method = "GET";
12976 request1.url = GURL("https://www.a.com/");
12977 request1.load_flags = 0;
12978 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012979 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312980
12981 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
12982 EXPECT_EQ(ERR_IO_PENDING, rv);
12983 EXPECT_EQ(OK, callback.WaitForResult());
12984
12985 const HttpResponseInfo* response = trans->GetResponseInfo();
12986 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012987 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312988 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12989 EXPECT_TRUE(response->was_fetched_via_spdy);
12990 EXPECT_TRUE(response->was_npn_negotiated);
12991
12992 std::string response_data;
12993 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12994 EXPECT_EQ("hello!", response_data);
12995 trans.reset();
12996 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612997 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312998
12999 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4013000 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5313001 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313002 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613003 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313004 HttpRequestInfo request2;
13005 request2.method = "GET";
13006 request2.url = GURL("https://www.b.com/");
13007 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013008 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313009
13010 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
13011 EXPECT_EQ(ERR_IO_PENDING, rv);
13012 EXPECT_EQ(OK, callback.WaitForResult());
13013
13014 response = trans->GetResponseInfo();
13015 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013016 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313017 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13018 EXPECT_TRUE(response->was_fetched_via_spdy);
13019 EXPECT_TRUE(response->was_npn_negotiated);
13020 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13021 EXPECT_EQ("hello!", response_data);
13022 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613023 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313024 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613025 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313026
13027 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4013028 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5313029 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313030 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613031 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0313032 HttpRequestInfo request3;
13033 request3.method = "GET";
13034 request3.url = GURL("http://www.a.com/");
13035 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013036 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313037
13038 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
13039 EXPECT_EQ(ERR_IO_PENDING, rv);
13040 EXPECT_EQ(OK, callback.WaitForResult());
13041
13042 response = trans->GetResponseInfo();
13043 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013044 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313045 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13046 EXPECT_FALSE(response->was_fetched_via_spdy);
13047 EXPECT_FALSE(response->was_npn_negotiated);
13048 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13049 EXPECT_EQ("hello!", response_data);
13050 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613051 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313052 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613053 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313054}
13055
[email protected]79e1fd62013-06-20 06:50:0413056TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
13057 HttpRequestInfo request;
13058 request.method = "GET";
bncce36dca22015-04-21 22:11:2313059 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413060 request.load_flags = 0;
13061
[email protected]3fe8d2f82013-10-17 08:56:0713062 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413063 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113064 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413065
13066 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
13067 StaticSocketDataProvider data;
13068 data.set_connect_data(mock_connect);
13069 session_deps_.socket_factory->AddSocketDataProvider(&data);
13070
13071 TestCompletionCallback callback;
13072
13073 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13074 EXPECT_EQ(ERR_IO_PENDING, rv);
13075
13076 rv = callback.WaitForResult();
13077 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13078
[email protected]79e1fd62013-06-20 06:50:0413079 // We don't care whether this succeeds or fails, but it shouldn't crash.
13080 HttpRequestHeaders request_headers;
13081 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713082
13083 ConnectionAttempts attempts;
13084 trans->GetConnectionAttempts(&attempts);
13085 ASSERT_EQ(1u, attempts.size());
13086 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0413087}
13088
13089TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
13090 HttpRequestInfo request;
13091 request.method = "GET";
bncce36dca22015-04-21 22:11:2313092 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413093 request.load_flags = 0;
13094
[email protected]3fe8d2f82013-10-17 08:56:0713095 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413096 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113097 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413098
13099 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13100 StaticSocketDataProvider data;
13101 data.set_connect_data(mock_connect);
13102 session_deps_.socket_factory->AddSocketDataProvider(&data);
13103
13104 TestCompletionCallback callback;
13105
13106 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13107 EXPECT_EQ(ERR_IO_PENDING, rv);
13108
13109 rv = callback.WaitForResult();
13110 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13111
[email protected]79e1fd62013-06-20 06:50:0413112 // We don't care whether this succeeds or fails, but it shouldn't crash.
13113 HttpRequestHeaders request_headers;
13114 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713115
13116 ConnectionAttempts attempts;
13117 trans->GetConnectionAttempts(&attempts);
13118 ASSERT_EQ(1u, attempts.size());
13119 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0413120}
13121
13122TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
13123 HttpRequestInfo request;
13124 request.method = "GET";
bncce36dca22015-04-21 22:11:2313125 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413126 request.load_flags = 0;
13127
[email protected]3fe8d2f82013-10-17 08:56:0713128 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413129 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113130 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413131
13132 MockWrite data_writes[] = {
13133 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13134 };
13135 MockRead data_reads[] = {
13136 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13137 };
13138
13139 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13140 data_writes, arraysize(data_writes));
13141 session_deps_.socket_factory->AddSocketDataProvider(&data);
13142
13143 TestCompletionCallback callback;
13144
13145 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13146 EXPECT_EQ(ERR_IO_PENDING, rv);
13147
13148 rv = callback.WaitForResult();
13149 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13150
[email protected]79e1fd62013-06-20 06:50:0413151 HttpRequestHeaders request_headers;
13152 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13153 EXPECT_TRUE(request_headers.HasHeader("Host"));
13154}
13155
13156TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
13157 HttpRequestInfo request;
13158 request.method = "GET";
bncce36dca22015-04-21 22:11:2313159 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413160 request.load_flags = 0;
13161
[email protected]3fe8d2f82013-10-17 08:56:0713162 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413163 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113164 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413165
13166 MockWrite data_writes[] = {
13167 MockWrite(ASYNC, ERR_CONNECTION_RESET),
13168 };
13169 MockRead data_reads[] = {
13170 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13171 };
13172
13173 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13174 data_writes, arraysize(data_writes));
13175 session_deps_.socket_factory->AddSocketDataProvider(&data);
13176
13177 TestCompletionCallback callback;
13178
13179 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13180 EXPECT_EQ(ERR_IO_PENDING, rv);
13181
13182 rv = callback.WaitForResult();
13183 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13184
[email protected]79e1fd62013-06-20 06:50:0413185 HttpRequestHeaders request_headers;
13186 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13187 EXPECT_TRUE(request_headers.HasHeader("Host"));
13188}
13189
13190TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
13191 HttpRequestInfo request;
13192 request.method = "GET";
bncce36dca22015-04-21 22:11:2313193 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413194 request.load_flags = 0;
13195
[email protected]3fe8d2f82013-10-17 08:56:0713196 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413197 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113198 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413199
13200 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313201 MockWrite(
13202 "GET / HTTP/1.1\r\n"
13203 "Host: www.example.org\r\n"
13204 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413205 };
13206 MockRead data_reads[] = {
13207 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
13208 };
13209
13210 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13211 data_writes, arraysize(data_writes));
13212 session_deps_.socket_factory->AddSocketDataProvider(&data);
13213
13214 TestCompletionCallback callback;
13215
13216 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13217 EXPECT_EQ(ERR_IO_PENDING, rv);
13218
13219 rv = callback.WaitForResult();
13220 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13221
[email protected]79e1fd62013-06-20 06:50:0413222 HttpRequestHeaders request_headers;
13223 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13224 EXPECT_TRUE(request_headers.HasHeader("Host"));
13225}
13226
13227TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
13228 HttpRequestInfo request;
13229 request.method = "GET";
bncce36dca22015-04-21 22:11:2313230 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413231 request.load_flags = 0;
13232
[email protected]3fe8d2f82013-10-17 08:56:0713233 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413234 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113235 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413236
13237 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313238 MockWrite(
13239 "GET / HTTP/1.1\r\n"
13240 "Host: www.example.org\r\n"
13241 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413242 };
13243 MockRead data_reads[] = {
13244 MockRead(ASYNC, ERR_CONNECTION_RESET),
13245 };
13246
13247 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13248 data_writes, arraysize(data_writes));
13249 session_deps_.socket_factory->AddSocketDataProvider(&data);
13250
13251 TestCompletionCallback callback;
13252
13253 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13254 EXPECT_EQ(ERR_IO_PENDING, rv);
13255
13256 rv = callback.WaitForResult();
13257 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13258
[email protected]79e1fd62013-06-20 06:50:0413259 HttpRequestHeaders request_headers;
13260 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13261 EXPECT_TRUE(request_headers.HasHeader("Host"));
13262}
13263
13264TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
13265 HttpRequestInfo request;
13266 request.method = "GET";
bncce36dca22015-04-21 22:11:2313267 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413268 request.load_flags = 0;
13269 request.extra_headers.SetHeader("X-Foo", "bar");
13270
[email protected]3fe8d2f82013-10-17 08:56:0713271 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413272 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113273 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413274
13275 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313276 MockWrite(
13277 "GET / HTTP/1.1\r\n"
13278 "Host: www.example.org\r\n"
13279 "Connection: keep-alive\r\n"
13280 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413281 };
13282 MockRead data_reads[] = {
13283 MockRead("HTTP/1.1 200 OK\r\n"
13284 "Content-Length: 5\r\n\r\n"
13285 "hello"),
13286 MockRead(ASYNC, ERR_UNEXPECTED),
13287 };
13288
13289 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13290 data_writes, arraysize(data_writes));
13291 session_deps_.socket_factory->AddSocketDataProvider(&data);
13292
13293 TestCompletionCallback callback;
13294
13295 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13296 EXPECT_EQ(ERR_IO_PENDING, rv);
13297
13298 rv = callback.WaitForResult();
13299 EXPECT_EQ(OK, rv);
13300
13301 HttpRequestHeaders request_headers;
13302 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13303 std::string foo;
13304 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
13305 EXPECT_EQ("bar", foo);
13306}
13307
[email protected]bf828982013-08-14 18:01:4713308namespace {
13309
yhiranoa7e05bb2014-11-06 05:40:3913310// Fake HttpStream that simply records calls to SetPriority().
13311class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0313312 public base::SupportsWeakPtr<FakeStream> {
13313 public:
13314 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2013315 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0313316
13317 RequestPriority priority() const { return priority_; }
13318
dchengb03027d2014-10-21 12:00:2013319 int InitializeStream(const HttpRequestInfo* request_info,
13320 RequestPriority priority,
13321 const BoundNetLog& net_log,
13322 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313323 return ERR_IO_PENDING;
13324 }
13325
dchengb03027d2014-10-21 12:00:2013326 int SendRequest(const HttpRequestHeaders& request_headers,
13327 HttpResponseInfo* response,
13328 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313329 ADD_FAILURE();
13330 return ERR_UNEXPECTED;
13331 }
13332
dchengb03027d2014-10-21 12:00:2013333 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313334 ADD_FAILURE();
13335 return ERR_UNEXPECTED;
13336 }
13337
dchengb03027d2014-10-21 12:00:2013338 int ReadResponseBody(IOBuffer* buf,
13339 int buf_len,
13340 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313341 ADD_FAILURE();
13342 return ERR_UNEXPECTED;
13343 }
13344
dchengb03027d2014-10-21 12:00:2013345 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0313346
dchengb03027d2014-10-21 12:00:2013347 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0313348 ADD_FAILURE();
13349 return false;
13350 }
13351
dchengb03027d2014-10-21 12:00:2013352 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0313353
dchengb03027d2014-10-21 12:00:2013354 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0313355 ADD_FAILURE();
13356 return false;
13357 }
13358
dchengb03027d2014-10-21 12:00:2013359 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313360
dchengb03027d2014-10-21 12:00:2013361 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0313362 ADD_FAILURE();
13363 return false;
13364 }
13365
dchengb03027d2014-10-21 12:00:2013366 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5913367 ADD_FAILURE();
13368 return 0;
13369 }
13370
dchengb03027d2014-10-21 12:00:2013371 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0313372 ADD_FAILURE();
13373 return false;
13374 }
13375
dchengb03027d2014-10-21 12:00:2013376 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
13377
13378 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0313379 ADD_FAILURE();
13380 }
13381
dchengb03027d2014-10-21 12:00:2013382 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0313383 ADD_FAILURE();
13384 return false;
13385 }
13386
dchengb03027d2014-10-21 12:00:2013387 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313388
dchengb03027d2014-10-21 12:00:2013389 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0313390
yhiranoa7e05bb2014-11-06 05:40:3913391 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
13392
13393 HttpStream* RenewStreamForAuth() override { return NULL; }
13394
[email protected]e86839fd2013-08-14 18:29:0313395 private:
13396 RequestPriority priority_;
13397
13398 DISALLOW_COPY_AND_ASSIGN(FakeStream);
13399};
13400
13401// Fake HttpStreamRequest that simply records calls to SetPriority()
13402// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4713403class FakeStreamRequest : public HttpStreamRequest,
13404 public base::SupportsWeakPtr<FakeStreamRequest> {
13405 public:
[email protected]e86839fd2013-08-14 18:29:0313406 FakeStreamRequest(RequestPriority priority,
13407 HttpStreamRequest::Delegate* delegate)
13408 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4413409 delegate_(delegate),
13410 websocket_stream_create_helper_(NULL) {}
13411
13412 FakeStreamRequest(RequestPriority priority,
13413 HttpStreamRequest::Delegate* delegate,
13414 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
13415 : priority_(priority),
13416 delegate_(delegate),
13417 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0313418
dchengb03027d2014-10-21 12:00:2013419 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4713420
13421 RequestPriority priority() const { return priority_; }
13422
[email protected]831e4a32013-11-14 02:14:4413423 const WebSocketHandshakeStreamBase::CreateHelper*
13424 websocket_stream_create_helper() const {
13425 return websocket_stream_create_helper_;
13426 }
13427
[email protected]e86839fd2013-08-14 18:29:0313428 // Create a new FakeStream and pass it to the request's
13429 // delegate. Returns a weak pointer to the FakeStream.
13430 base::WeakPtr<FakeStream> FinishStreamRequest() {
13431 FakeStream* fake_stream = new FakeStream(priority_);
13432 // Do this before calling OnStreamReady() as OnStreamReady() may
13433 // immediately delete |fake_stream|.
13434 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
13435 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
13436 return weak_stream;
13437 }
13438
dchengb03027d2014-10-21 12:00:2013439 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4713440 ADD_FAILURE();
13441 return ERR_UNEXPECTED;
13442 }
13443
dchengb03027d2014-10-21 12:00:2013444 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4713445 ADD_FAILURE();
13446 return LoadState();
13447 }
13448
dchengb03027d2014-10-21 12:00:2013449 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4713450
dchengb03027d2014-10-21 12:00:2013451 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713452
dchengb03027d2014-10-21 12:00:2013453 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4713454
dchengb03027d2014-10-21 12:00:2013455 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713456
ttuttle1f2d7e92015-04-28 16:17:4713457 const ConnectionAttempts& connection_attempts() const override {
13458 static ConnectionAttempts no_attempts;
13459 return no_attempts;
13460 }
13461
[email protected]bf828982013-08-14 18:01:4713462 private:
13463 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0313464 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4413465 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4713466
13467 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
13468};
13469
13470// Fake HttpStreamFactory that vends FakeStreamRequests.
13471class FakeStreamFactory : public HttpStreamFactory {
13472 public:
13473 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2013474 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4713475
13476 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
13477 // RequestStream() (which may be NULL if it was destroyed already).
13478 base::WeakPtr<FakeStreamRequest> last_stream_request() {
13479 return last_stream_request_;
13480 }
13481
dchengb03027d2014-10-21 12:00:2013482 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
13483 RequestPriority priority,
13484 const SSLConfig& server_ssl_config,
13485 const SSLConfig& proxy_ssl_config,
13486 HttpStreamRequest::Delegate* delegate,
13487 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0313488 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4713489 last_stream_request_ = fake_request->AsWeakPtr();
13490 return fake_request;
13491 }
13492
dchengb03027d2014-10-21 12:00:2013493 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4713494 const HttpRequestInfo& info,
13495 RequestPriority priority,
13496 const SSLConfig& server_ssl_config,
13497 const SSLConfig& proxy_ssl_config,
13498 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4613499 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1313500 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4413501 FakeStreamRequest* fake_request =
13502 new FakeStreamRequest(priority, delegate, create_helper);
13503 last_stream_request_ = fake_request->AsWeakPtr();
13504 return fake_request;
[email protected]bf828982013-08-14 18:01:4713505 }
13506
dchengb03027d2014-10-21 12:00:2013507 void PreconnectStreams(int num_streams,
13508 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2013509 const SSLConfig& server_ssl_config,
13510 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4713511 ADD_FAILURE();
13512 }
13513
dchengb03027d2014-10-21 12:00:2013514 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4713515 ADD_FAILURE();
13516 return NULL;
13517 }
13518
13519 private:
13520 base::WeakPtr<FakeStreamRequest> last_stream_request_;
13521
13522 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
13523};
13524
Adam Rice425cf122015-01-19 06:18:2413525// TODO(ricea): Maybe unify this with the one in
13526// url_request_http_job_unittest.cc ?
13527class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
13528 public:
13529 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
13530 bool using_proxy)
13531 : state_(connection.release(), using_proxy) {}
13532
13533 // Fake implementation of HttpStreamBase methods.
13534 // This ends up being quite "real" because this object has to really send data
13535 // on the mock socket. It might be easier to use the real implementation, but
13536 // the fact that the WebSocket code is not compiled on iOS makes that
13537 // difficult.
13538 int InitializeStream(const HttpRequestInfo* request_info,
13539 RequestPriority priority,
13540 const BoundNetLog& net_log,
13541 const CompletionCallback& callback) override {
13542 state_.Initialize(request_info, priority, net_log, callback);
13543 return OK;
13544 }
13545
13546 int SendRequest(const HttpRequestHeaders& request_headers,
13547 HttpResponseInfo* response,
13548 const CompletionCallback& callback) override {
13549 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
13550 response, callback);
13551 }
13552
13553 int ReadResponseHeaders(const CompletionCallback& callback) override {
13554 return parser()->ReadResponseHeaders(callback);
13555 }
13556
13557 int ReadResponseBody(IOBuffer* buf,
13558 int buf_len,
13559 const CompletionCallback& callback) override {
13560 NOTREACHED();
13561 return ERR_IO_PENDING;
13562 }
13563
13564 void Close(bool not_reusable) override {
13565 if (parser())
13566 parser()->Close(true);
13567 }
13568
13569 bool IsResponseBodyComplete() const override {
13570 NOTREACHED();
13571 return false;
13572 }
13573
13574 bool CanFindEndOfResponse() const override {
13575 return parser()->CanFindEndOfResponse();
13576 }
13577
13578 bool IsConnectionReused() const override {
13579 NOTREACHED();
13580 return false;
13581 }
13582 void SetConnectionReused() override { NOTREACHED(); }
13583
13584 bool IsConnectionReusable() const override {
13585 NOTREACHED();
13586 return false;
13587 }
13588
13589 int64 GetTotalReceivedBytes() const override {
13590 NOTREACHED();
13591 return 0;
13592 }
13593
13594 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13595 NOTREACHED();
13596 return false;
13597 }
13598
Adam Ricecb76ac62015-02-20 05:33:2513599 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413600
13601 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13602 NOTREACHED();
13603 }
13604
13605 bool IsSpdyHttpStream() const override {
13606 NOTREACHED();
13607 return false;
13608 }
13609
13610 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13611
13612 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13613
13614 UploadProgress GetUploadProgress() const override {
13615 NOTREACHED();
13616 return UploadProgress();
13617 }
13618
13619 HttpStream* RenewStreamForAuth() override {
13620 NOTREACHED();
13621 return nullptr;
13622 }
13623
13624 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13625 scoped_ptr<WebSocketStream> Upgrade() override {
13626 NOTREACHED();
13627 return scoped_ptr<WebSocketStream>();
13628 }
13629
13630 private:
13631 HttpStreamParser* parser() const { return state_.parser(); }
13632 HttpBasicState state_;
13633
13634 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13635};
13636
[email protected]831e4a32013-11-14 02:14:4413637// TODO(yhirano): Split this class out into a net/websockets file, if it is
13638// worth doing.
13639class FakeWebSocketStreamCreateHelper :
13640 public WebSocketHandshakeStreamBase::CreateHelper {
13641 public:
dchengb03027d2014-10-21 12:00:2013642 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113643 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313644 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413645 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13646 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413647 }
13648
dchengb03027d2014-10-21 12:00:2013649 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413650 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313651 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413652 NOTREACHED();
13653 return NULL;
13654 };
13655
dchengb03027d2014-10-21 12:00:2013656 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413657
13658 virtual scoped_ptr<WebSocketStream> Upgrade() {
13659 NOTREACHED();
13660 return scoped_ptr<WebSocketStream>();
13661 }
13662};
13663
[email protected]bf828982013-08-14 18:01:4713664} // namespace
13665
13666// Make sure that HttpNetworkTransaction passes on its priority to its
13667// stream request on start.
13668TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
13669 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13670 HttpNetworkSessionPeer peer(session);
13671 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413672 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713673
dcheng48459ac22014-08-26 00:46:4113674 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713675
13676 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13677
13678 HttpRequestInfo request;
13679 TestCompletionCallback callback;
13680 EXPECT_EQ(ERR_IO_PENDING,
13681 trans.Start(&request, callback.callback(), BoundNetLog()));
13682
13683 base::WeakPtr<FakeStreamRequest> fake_request =
13684 fake_factory->last_stream_request();
13685 ASSERT_TRUE(fake_request != NULL);
13686 EXPECT_EQ(LOW, fake_request->priority());
13687}
13688
13689// Make sure that HttpNetworkTransaction passes on its priority
13690// updates to its stream request.
13691TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
13692 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13693 HttpNetworkSessionPeer peer(session);
13694 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413695 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713696
dcheng48459ac22014-08-26 00:46:4113697 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713698
13699 HttpRequestInfo request;
13700 TestCompletionCallback callback;
13701 EXPECT_EQ(ERR_IO_PENDING,
13702 trans.Start(&request, callback.callback(), BoundNetLog()));
13703
13704 base::WeakPtr<FakeStreamRequest> fake_request =
13705 fake_factory->last_stream_request();
13706 ASSERT_TRUE(fake_request != NULL);
13707 EXPECT_EQ(LOW, fake_request->priority());
13708
13709 trans.SetPriority(LOWEST);
13710 ASSERT_TRUE(fake_request != NULL);
13711 EXPECT_EQ(LOWEST, fake_request->priority());
13712}
13713
[email protected]e86839fd2013-08-14 18:29:0313714// Make sure that HttpNetworkTransaction passes on its priority
13715// updates to its stream.
13716TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
13717 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13718 HttpNetworkSessionPeer peer(session);
13719 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413720 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313721
dcheng48459ac22014-08-26 00:46:4113722 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313723
13724 HttpRequestInfo request;
13725 TestCompletionCallback callback;
13726 EXPECT_EQ(ERR_IO_PENDING,
13727 trans.Start(&request, callback.callback(), BoundNetLog()));
13728
13729 base::WeakPtr<FakeStreamRequest> fake_request =
13730 fake_factory->last_stream_request();
13731 ASSERT_TRUE(fake_request != NULL);
13732 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13733 ASSERT_TRUE(fake_stream != NULL);
13734 EXPECT_EQ(LOW, fake_stream->priority());
13735
13736 trans.SetPriority(LOWEST);
13737 EXPECT_EQ(LOWEST, fake_stream->priority());
13738}
13739
[email protected]831e4a32013-11-14 02:14:4413740TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13741 // The same logic needs to be tested for both ws: and wss: schemes, but this
13742 // test is already parameterised on NextProto, so it uses a loop to verify
13743 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313744 std::string test_cases[] = {"ws://www.example.org/",
13745 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413746 for (size_t i = 0; i < arraysize(test_cases); ++i) {
13747 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13748 HttpNetworkSessionPeer peer(session);
13749 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13750 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313751 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413752 scoped_ptr<HttpStreamFactory>(fake_factory));
13753
dcheng48459ac22014-08-26 00:46:4113754 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413755 trans.SetWebSocketHandshakeStreamCreateHelper(
13756 &websocket_stream_create_helper);
13757
13758 HttpRequestInfo request;
13759 TestCompletionCallback callback;
13760 request.method = "GET";
13761 request.url = GURL(test_cases[i]);
13762
13763 EXPECT_EQ(ERR_IO_PENDING,
13764 trans.Start(&request, callback.callback(), BoundNetLog()));
13765
13766 base::WeakPtr<FakeStreamRequest> fake_request =
13767 fake_factory->last_stream_request();
13768 ASSERT_TRUE(fake_request != NULL);
13769 EXPECT_EQ(&websocket_stream_create_helper,
13770 fake_request->websocket_stream_create_helper());
13771 }
13772}
13773
[email protected]043b68c82013-08-22 23:41:5213774// Tests that when a used socket is returned to the SSL socket pool, it's closed
13775// if the transport socket pool is stalled on the global socket limit.
13776TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13777 ClientSocketPoolManager::set_max_sockets_per_group(
13778 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13779 ClientSocketPoolManager::set_max_sockets_per_pool(
13780 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13781
13782 // Set up SSL request.
13783
13784 HttpRequestInfo ssl_request;
13785 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313786 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213787
13788 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313789 MockWrite(
13790 "GET / HTTP/1.1\r\n"
13791 "Host: www.example.org\r\n"
13792 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213793 };
13794 MockRead ssl_reads[] = {
13795 MockRead("HTTP/1.1 200 OK\r\n"),
13796 MockRead("Content-Length: 11\r\n\r\n"),
13797 MockRead("hello world"),
13798 MockRead(SYNCHRONOUS, OK),
13799 };
13800 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13801 ssl_writes, arraysize(ssl_writes));
13802 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13803
13804 SSLSocketDataProvider ssl(ASYNC, OK);
13805 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13806
13807 // Set up HTTP request.
13808
13809 HttpRequestInfo http_request;
13810 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313811 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213812
13813 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313814 MockWrite(
13815 "GET / HTTP/1.1\r\n"
13816 "Host: www.example.org\r\n"
13817 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213818 };
13819 MockRead http_reads[] = {
13820 MockRead("HTTP/1.1 200 OK\r\n"),
13821 MockRead("Content-Length: 7\r\n\r\n"),
13822 MockRead("falafel"),
13823 MockRead(SYNCHRONOUS, OK),
13824 };
13825 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13826 http_writes, arraysize(http_writes));
13827 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13828
13829 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13830
13831 // Start the SSL request.
13832 TestCompletionCallback ssl_callback;
13833 scoped_ptr<HttpTransaction> ssl_trans(
13834 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13835 ASSERT_EQ(ERR_IO_PENDING,
13836 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13837 BoundNetLog()));
13838
13839 // Start the HTTP request. Pool should stall.
13840 TestCompletionCallback http_callback;
13841 scoped_ptr<HttpTransaction> http_trans(
13842 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13843 ASSERT_EQ(ERR_IO_PENDING,
13844 http_trans->Start(&http_request, http_callback.callback(),
13845 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113846 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213847
13848 // Wait for response from SSL request.
13849 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13850 std::string response_data;
13851 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13852 EXPECT_EQ("hello world", response_data);
13853
13854 // The SSL socket should automatically be closed, so the HTTP request can
13855 // start.
dcheng48459ac22014-08-26 00:46:4113856 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13857 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213858
13859 // The HTTP request can now complete.
13860 ASSERT_EQ(OK, http_callback.WaitForResult());
13861 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13862 EXPECT_EQ("falafel", response_data);
13863
dcheng48459ac22014-08-26 00:46:4113864 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213865}
13866
13867// Tests that when a SSL connection is established but there's no corresponding
13868// request that needs it, the new socket is closed if the transport socket pool
13869// is stalled on the global socket limit.
13870TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13871 ClientSocketPoolManager::set_max_sockets_per_group(
13872 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13873 ClientSocketPoolManager::set_max_sockets_per_pool(
13874 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13875
13876 // Set up an ssl request.
13877
13878 HttpRequestInfo ssl_request;
13879 ssl_request.method = "GET";
13880 ssl_request.url = GURL("https://www.foopy.com/");
13881
13882 // No data will be sent on the SSL socket.
13883 StaticSocketDataProvider ssl_data;
13884 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13885
13886 SSLSocketDataProvider ssl(ASYNC, OK);
13887 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13888
13889 // Set up HTTP request.
13890
13891 HttpRequestInfo http_request;
13892 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313893 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213894
13895 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313896 MockWrite(
13897 "GET / HTTP/1.1\r\n"
13898 "Host: www.example.org\r\n"
13899 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213900 };
13901 MockRead http_reads[] = {
13902 MockRead("HTTP/1.1 200 OK\r\n"),
13903 MockRead("Content-Length: 7\r\n\r\n"),
13904 MockRead("falafel"),
13905 MockRead(SYNCHRONOUS, OK),
13906 };
13907 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13908 http_writes, arraysize(http_writes));
13909 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13910
13911 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13912
13913 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13914 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2913915 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13916 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5213917 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd2015-07-15 22:26:3513918 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
13919 ssl_config);
dcheng48459ac22014-08-26 00:46:4113920 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213921
13922 // Start the HTTP request. Pool should stall.
13923 TestCompletionCallback http_callback;
13924 scoped_ptr<HttpTransaction> http_trans(
13925 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13926 ASSERT_EQ(ERR_IO_PENDING,
13927 http_trans->Start(&http_request, http_callback.callback(),
13928 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113929 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213930
13931 // The SSL connection will automatically be closed once the connection is
13932 // established, to let the HTTP request start.
13933 ASSERT_EQ(OK, http_callback.WaitForResult());
13934 std::string response_data;
13935 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13936 EXPECT_EQ("falafel", response_data);
13937
dcheng48459ac22014-08-26 00:46:4113938 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213939}
13940
[email protected]02d74a02014-04-23 18:10:5413941TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13942 ScopedVector<UploadElementReader> element_readers;
13943 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713944 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413945
13946 HttpRequestInfo request;
13947 request.method = "POST";
13948 request.url = GURL("http://www.foo.com/");
13949 request.upload_data_stream = &upload_data_stream;
13950 request.load_flags = 0;
13951
13952 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13953 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113954 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413955 // Send headers successfully, but get an error while sending the body.
13956 MockWrite data_writes[] = {
13957 MockWrite("POST / HTTP/1.1\r\n"
13958 "Host: www.foo.com\r\n"
13959 "Connection: keep-alive\r\n"
13960 "Content-Length: 3\r\n\r\n"),
13961 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13962 };
13963
13964 MockRead data_reads[] = {
13965 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13966 MockRead("hello world"),
13967 MockRead(SYNCHRONOUS, OK),
13968 };
13969 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13970 arraysize(data_writes));
13971 session_deps_.socket_factory->AddSocketDataProvider(&data);
13972
13973 TestCompletionCallback callback;
13974
13975 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13976 EXPECT_EQ(ERR_IO_PENDING, rv);
13977
13978 rv = callback.WaitForResult();
13979 EXPECT_EQ(OK, rv);
13980
13981 const HttpResponseInfo* response = trans->GetResponseInfo();
13982 ASSERT_TRUE(response != NULL);
13983
13984 EXPECT_TRUE(response->headers.get() != NULL);
13985 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13986
13987 std::string response_data;
13988 rv = ReadTransaction(trans.get(), &response_data);
13989 EXPECT_EQ(OK, rv);
13990 EXPECT_EQ("hello world", response_data);
13991}
13992
13993// This test makes sure the retry logic doesn't trigger when reading an error
13994// response from a server that rejected a POST with a CONNECTION_RESET.
13995TEST_P(HttpNetworkTransactionTest,
13996 PostReadsErrorResponseAfterResetOnReusedSocket) {
13997 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13998 MockWrite data_writes[] = {
13999 MockWrite("GET / HTTP/1.1\r\n"
14000 "Host: www.foo.com\r\n"
14001 "Connection: keep-alive\r\n\r\n"),
14002 MockWrite("POST / HTTP/1.1\r\n"
14003 "Host: www.foo.com\r\n"
14004 "Connection: keep-alive\r\n"
14005 "Content-Length: 3\r\n\r\n"),
14006 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14007 };
14008
14009 MockRead data_reads[] = {
14010 MockRead("HTTP/1.1 200 Peachy\r\n"
14011 "Content-Length: 14\r\n\r\n"),
14012 MockRead("first response"),
14013 MockRead("HTTP/1.1 400 Not OK\r\n"
14014 "Content-Length: 15\r\n\r\n"),
14015 MockRead("second response"),
14016 MockRead(SYNCHRONOUS, OK),
14017 };
14018 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14019 arraysize(data_writes));
14020 session_deps_.socket_factory->AddSocketDataProvider(&data);
14021
14022 TestCompletionCallback callback;
14023 HttpRequestInfo request1;
14024 request1.method = "GET";
14025 request1.url = GURL("http://www.foo.com/");
14026 request1.load_flags = 0;
14027
14028 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4114029 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414030 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
14031 EXPECT_EQ(ERR_IO_PENDING, rv);
14032
14033 rv = callback.WaitForResult();
14034 EXPECT_EQ(OK, rv);
14035
14036 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
14037 ASSERT_TRUE(response1 != NULL);
14038
14039 EXPECT_TRUE(response1->headers.get() != NULL);
14040 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
14041
14042 std::string response_data1;
14043 rv = ReadTransaction(trans1.get(), &response_data1);
14044 EXPECT_EQ(OK, rv);
14045 EXPECT_EQ("first response", response_data1);
14046 // Delete the transaction to release the socket back into the socket pool.
14047 trans1.reset();
14048
14049 ScopedVector<UploadElementReader> element_readers;
14050 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714051 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414052
14053 HttpRequestInfo request2;
14054 request2.method = "POST";
14055 request2.url = GURL("http://www.foo.com/");
14056 request2.upload_data_stream = &upload_data_stream;
14057 request2.load_flags = 0;
14058
14059 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4114060 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414061 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
14062 EXPECT_EQ(ERR_IO_PENDING, rv);
14063
14064 rv = callback.WaitForResult();
14065 EXPECT_EQ(OK, rv);
14066
14067 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
14068 ASSERT_TRUE(response2 != NULL);
14069
14070 EXPECT_TRUE(response2->headers.get() != NULL);
14071 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
14072
14073 std::string response_data2;
14074 rv = ReadTransaction(trans2.get(), &response_data2);
14075 EXPECT_EQ(OK, rv);
14076 EXPECT_EQ("second response", response_data2);
14077}
14078
14079TEST_P(HttpNetworkTransactionTest,
14080 PostReadsErrorResponseAfterResetPartialBodySent) {
14081 ScopedVector<UploadElementReader> element_readers;
14082 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714083 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414084
14085 HttpRequestInfo request;
14086 request.method = "POST";
14087 request.url = GURL("http://www.foo.com/");
14088 request.upload_data_stream = &upload_data_stream;
14089 request.load_flags = 0;
14090
14091 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14092 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114093 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414094 // Send headers successfully, but get an error while sending the body.
14095 MockWrite data_writes[] = {
14096 MockWrite("POST / HTTP/1.1\r\n"
14097 "Host: www.foo.com\r\n"
14098 "Connection: keep-alive\r\n"
14099 "Content-Length: 3\r\n\r\n"
14100 "fo"),
14101 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14102 };
14103
14104 MockRead data_reads[] = {
14105 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14106 MockRead("hello world"),
14107 MockRead(SYNCHRONOUS, OK),
14108 };
14109 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14110 arraysize(data_writes));
14111 session_deps_.socket_factory->AddSocketDataProvider(&data);
14112
14113 TestCompletionCallback callback;
14114
14115 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14116 EXPECT_EQ(ERR_IO_PENDING, rv);
14117
14118 rv = callback.WaitForResult();
14119 EXPECT_EQ(OK, rv);
14120
14121 const HttpResponseInfo* response = trans->GetResponseInfo();
14122 ASSERT_TRUE(response != NULL);
14123
14124 EXPECT_TRUE(response->headers.get() != NULL);
14125 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14126
14127 std::string response_data;
14128 rv = ReadTransaction(trans.get(), &response_data);
14129 EXPECT_EQ(OK, rv);
14130 EXPECT_EQ("hello world", response_data);
14131}
14132
14133// This tests the more common case than the previous test, where headers and
14134// body are not merged into a single request.
14135TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
14136 ScopedVector<UploadElementReader> element_readers;
14137 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714138 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5414139
14140 HttpRequestInfo request;
14141 request.method = "POST";
14142 request.url = GURL("http://www.foo.com/");
14143 request.upload_data_stream = &upload_data_stream;
14144 request.load_flags = 0;
14145
14146 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14147 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114148 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414149 // Send headers successfully, but get an error while sending the body.
14150 MockWrite data_writes[] = {
14151 MockWrite("POST / HTTP/1.1\r\n"
14152 "Host: www.foo.com\r\n"
14153 "Connection: keep-alive\r\n"
14154 "Transfer-Encoding: chunked\r\n\r\n"),
14155 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14156 };
14157
14158 MockRead data_reads[] = {
14159 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14160 MockRead("hello world"),
14161 MockRead(SYNCHRONOUS, OK),
14162 };
14163 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14164 arraysize(data_writes));
14165 session_deps_.socket_factory->AddSocketDataProvider(&data);
14166
14167 TestCompletionCallback callback;
14168
14169 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14170 EXPECT_EQ(ERR_IO_PENDING, rv);
14171 // Make sure the headers are sent before adding a chunk. This ensures that
14172 // they can't be merged with the body in a single send. Not currently
14173 // necessary since a chunked body is never merged with headers, but this makes
14174 // the test more future proof.
14175 base::RunLoop().RunUntilIdle();
14176
mmenkecbc2b712014-10-09 20:29:0714177 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5414178
14179 rv = callback.WaitForResult();
14180 EXPECT_EQ(OK, rv);
14181
14182 const HttpResponseInfo* response = trans->GetResponseInfo();
14183 ASSERT_TRUE(response != NULL);
14184
14185 EXPECT_TRUE(response->headers.get() != NULL);
14186 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14187
14188 std::string response_data;
14189 rv = ReadTransaction(trans.get(), &response_data);
14190 EXPECT_EQ(OK, rv);
14191 EXPECT_EQ("hello world", response_data);
14192}
14193
14194TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
14195 ScopedVector<UploadElementReader> element_readers;
14196 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714197 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414198
14199 HttpRequestInfo request;
14200 request.method = "POST";
14201 request.url = GURL("http://www.foo.com/");
14202 request.upload_data_stream = &upload_data_stream;
14203 request.load_flags = 0;
14204
14205 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14206 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114207 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414208
14209 MockWrite data_writes[] = {
14210 MockWrite("POST / HTTP/1.1\r\n"
14211 "Host: www.foo.com\r\n"
14212 "Connection: keep-alive\r\n"
14213 "Content-Length: 3\r\n\r\n"),
14214 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14215 };
14216
14217 MockRead data_reads[] = {
14218 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14219 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14220 MockRead("hello world"),
14221 MockRead(SYNCHRONOUS, OK),
14222 };
14223 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14224 arraysize(data_writes));
14225 session_deps_.socket_factory->AddSocketDataProvider(&data);
14226
14227 TestCompletionCallback callback;
14228
14229 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14230 EXPECT_EQ(ERR_IO_PENDING, rv);
14231
14232 rv = callback.WaitForResult();
14233 EXPECT_EQ(OK, rv);
14234
14235 const HttpResponseInfo* response = trans->GetResponseInfo();
14236 ASSERT_TRUE(response != NULL);
14237
14238 EXPECT_TRUE(response->headers.get() != NULL);
14239 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14240
14241 std::string response_data;
14242 rv = ReadTransaction(trans.get(), &response_data);
14243 EXPECT_EQ(OK, rv);
14244 EXPECT_EQ("hello world", response_data);
14245}
14246
14247TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
14248 ScopedVector<UploadElementReader> element_readers;
14249 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714250 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414251
14252 HttpRequestInfo request;
14253 request.method = "POST";
14254 request.url = GURL("http://www.foo.com/");
14255 request.upload_data_stream = &upload_data_stream;
14256 request.load_flags = 0;
14257
14258 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14259 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114260 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414261 // Send headers successfully, but get an error while sending the body.
14262 MockWrite data_writes[] = {
14263 MockWrite("POST / HTTP/1.1\r\n"
14264 "Host: www.foo.com\r\n"
14265 "Connection: keep-alive\r\n"
14266 "Content-Length: 3\r\n\r\n"),
14267 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14268 };
14269
14270 MockRead data_reads[] = {
14271 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
14272 MockRead("hello world"),
14273 MockRead(SYNCHRONOUS, OK),
14274 };
14275 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14276 arraysize(data_writes));
14277 session_deps_.socket_factory->AddSocketDataProvider(&data);
14278
14279 TestCompletionCallback callback;
14280
14281 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14282 EXPECT_EQ(ERR_IO_PENDING, rv);
14283
14284 rv = callback.WaitForResult();
14285 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414286}
14287
14288TEST_P(HttpNetworkTransactionTest,
14289 PostIgnoresNonErrorResponseAfterResetAnd100) {
14290 ScopedVector<UploadElementReader> element_readers;
14291 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714292 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414293
14294 HttpRequestInfo request;
14295 request.method = "POST";
14296 request.url = GURL("http://www.foo.com/");
14297 request.upload_data_stream = &upload_data_stream;
14298 request.load_flags = 0;
14299
14300 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14301 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114302 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414303 // Send headers successfully, but get an error while sending the body.
14304 MockWrite data_writes[] = {
14305 MockWrite("POST / HTTP/1.1\r\n"
14306 "Host: www.foo.com\r\n"
14307 "Connection: keep-alive\r\n"
14308 "Content-Length: 3\r\n\r\n"),
14309 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14310 };
14311
14312 MockRead data_reads[] = {
14313 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14314 MockRead("HTTP/1.0 302 Redirect\r\n"),
14315 MockRead("Location: http://somewhere-else.com/\r\n"),
14316 MockRead("Content-Length: 0\r\n\r\n"),
14317 MockRead(SYNCHRONOUS, OK),
14318 };
14319 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14320 arraysize(data_writes));
14321 session_deps_.socket_factory->AddSocketDataProvider(&data);
14322
14323 TestCompletionCallback callback;
14324
14325 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14326 EXPECT_EQ(ERR_IO_PENDING, rv);
14327
14328 rv = callback.WaitForResult();
14329 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414330}
14331
14332TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
14333 ScopedVector<UploadElementReader> element_readers;
14334 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714335 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414336
14337 HttpRequestInfo request;
14338 request.method = "POST";
14339 request.url = GURL("http://www.foo.com/");
14340 request.upload_data_stream = &upload_data_stream;
14341 request.load_flags = 0;
14342
14343 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14344 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414346 // Send headers successfully, but get an error while sending the body.
14347 MockWrite data_writes[] = {
14348 MockWrite("POST / HTTP/1.1\r\n"
14349 "Host: www.foo.com\r\n"
14350 "Connection: keep-alive\r\n"
14351 "Content-Length: 3\r\n\r\n"),
14352 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14353 };
14354
14355 MockRead data_reads[] = {
14356 MockRead("HTTP 0.9 rocks!"),
14357 MockRead(SYNCHRONOUS, OK),
14358 };
14359 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14360 arraysize(data_writes));
14361 session_deps_.socket_factory->AddSocketDataProvider(&data);
14362
14363 TestCompletionCallback callback;
14364
14365 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14366 EXPECT_EQ(ERR_IO_PENDING, rv);
14367
14368 rv = callback.WaitForResult();
14369 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414370}
14371
14372TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
14373 ScopedVector<UploadElementReader> element_readers;
14374 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714375 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414376
14377 HttpRequestInfo request;
14378 request.method = "POST";
14379 request.url = GURL("http://www.foo.com/");
14380 request.upload_data_stream = &upload_data_stream;
14381 request.load_flags = 0;
14382
14383 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14384 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114385 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414386 // Send headers successfully, but get an error while sending the body.
14387 MockWrite data_writes[] = {
14388 MockWrite("POST / HTTP/1.1\r\n"
14389 "Host: www.foo.com\r\n"
14390 "Connection: keep-alive\r\n"
14391 "Content-Length: 3\r\n\r\n"),
14392 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14393 };
14394
14395 MockRead data_reads[] = {
14396 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
14397 MockRead(SYNCHRONOUS, OK),
14398 };
14399 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14400 arraysize(data_writes));
14401 session_deps_.socket_factory->AddSocketDataProvider(&data);
14402
14403 TestCompletionCallback callback;
14404
14405 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14406 EXPECT_EQ(ERR_IO_PENDING, rv);
14407
14408 rv = callback.WaitForResult();
14409 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414410}
14411
Adam Rice425cf122015-01-19 06:18:2414412// Verify that proxy headers are not sent to the destination server when
14413// establishing a tunnel for a secure WebSocket connection.
14414TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
14415 HttpRequestInfo request;
14416 request.method = "GET";
bncce36dca22015-04-21 22:11:2314417 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414418 AddWebSocketHeaders(&request.extra_headers);
14419
14420 // Configure against proxy server "myproxy:70".
14421 session_deps_.proxy_service.reset(
14422 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14423
14424 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14425
14426 // Since a proxy is configured, try to establish a tunnel.
14427 MockWrite data_writes[] = {
14428 MockWrite(
bncce36dca22015-04-21 22:11:2314429 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14430 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414431 "Proxy-Connection: keep-alive\r\n\r\n"),
14432
14433 // After calling trans->RestartWithAuth(), this is the request we should
14434 // be issuing -- the final header line contains the credentials.
14435 MockWrite(
bncce36dca22015-04-21 22:11:2314436 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14437 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414438 "Proxy-Connection: keep-alive\r\n"
14439 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14440
14441 MockWrite(
14442 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314443 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414444 "Connection: Upgrade\r\n"
14445 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314446 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414447 "Sec-WebSocket-Version: 13\r\n"
14448 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14449 };
14450
14451 // The proxy responds to the connect with a 407, using a persistent
14452 // connection.
14453 MockRead data_reads[] = {
14454 // No credentials.
14455 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14456 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee0b5c882015-08-26 20:29:1114457 MockRead("Content-Length: 0\r\n"),
14458 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2414459
14460 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14461
14462 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14463 MockRead("Upgrade: websocket\r\n"),
14464 MockRead("Connection: Upgrade\r\n"),
14465 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14466 };
14467
14468 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14469 arraysize(data_writes));
14470 session_deps_.socket_factory->AddSocketDataProvider(&data);
14471 SSLSocketDataProvider ssl(ASYNC, OK);
14472 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14473
14474 scoped_ptr<HttpTransaction> trans(
14475 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14476 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14477 trans->SetWebSocketHandshakeStreamCreateHelper(
14478 &websocket_stream_create_helper);
14479
14480 {
14481 TestCompletionCallback callback;
14482
14483 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14484 EXPECT_EQ(ERR_IO_PENDING, rv);
14485
14486 rv = callback.WaitForResult();
14487 EXPECT_EQ(OK, rv);
14488 }
14489
14490 const HttpResponseInfo* response = trans->GetResponseInfo();
14491 ASSERT_TRUE(response);
14492 ASSERT_TRUE(response->headers.get());
14493 EXPECT_EQ(407, response->headers->response_code());
14494
14495 {
14496 TestCompletionCallback callback;
14497
14498 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
14499 callback.callback());
14500 EXPECT_EQ(ERR_IO_PENDING, rv);
14501
14502 rv = callback.WaitForResult();
14503 EXPECT_EQ(OK, rv);
14504 }
14505
14506 response = trans->GetResponseInfo();
14507 ASSERT_TRUE(response);
14508 ASSERT_TRUE(response->headers.get());
14509
14510 EXPECT_EQ(101, response->headers->response_code());
14511
14512 trans.reset();
14513 session->CloseAllConnections();
14514}
14515
14516// Verify that proxy headers are not sent to the destination server when
14517// establishing a tunnel for an insecure WebSocket connection.
14518// This requires the authentication info to be injected into the auth cache
14519// due to crbug.com/395064
14520// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
14521TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
14522 HttpRequestInfo request;
14523 request.method = "GET";
bncce36dca22015-04-21 22:11:2314524 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414525 AddWebSocketHeaders(&request.extra_headers);
14526
14527 // Configure against proxy server "myproxy:70".
14528 session_deps_.proxy_service.reset(
14529 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14530
14531 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14532
14533 MockWrite data_writes[] = {
14534 // Try to establish a tunnel for the WebSocket connection, with
14535 // credentials. Because WebSockets have a separate set of socket pools,
14536 // they cannot and will not use the same TCP/IP connection as the
14537 // preflight HTTP request.
14538 MockWrite(
bncce36dca22015-04-21 22:11:2314539 "CONNECT www.example.org:80 HTTP/1.1\r\n"
14540 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2414541 "Proxy-Connection: keep-alive\r\n"
14542 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14543
14544 MockWrite(
14545 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314546 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414547 "Connection: Upgrade\r\n"
14548 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314549 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414550 "Sec-WebSocket-Version: 13\r\n"
14551 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14552 };
14553
14554 MockRead data_reads[] = {
14555 // HTTP CONNECT with credentials.
14556 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14557
14558 // WebSocket connection established inside tunnel.
14559 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14560 MockRead("Upgrade: websocket\r\n"),
14561 MockRead("Connection: Upgrade\r\n"),
14562 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14563 };
14564
14565 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14566 arraysize(data_writes));
14567 session_deps_.socket_factory->AddSocketDataProvider(&data);
14568
14569 session->http_auth_cache()->Add(
14570 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
14571 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
14572
14573 scoped_ptr<HttpTransaction> trans(
14574 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14575 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14576 trans->SetWebSocketHandshakeStreamCreateHelper(
14577 &websocket_stream_create_helper);
14578
14579 TestCompletionCallback callback;
14580
14581 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14582 EXPECT_EQ(ERR_IO_PENDING, rv);
14583
14584 rv = callback.WaitForResult();
14585 EXPECT_EQ(OK, rv);
14586
14587 const HttpResponseInfo* response = trans->GetResponseInfo();
14588 ASSERT_TRUE(response);
14589 ASSERT_TRUE(response->headers.get());
14590
14591 EXPECT_EQ(101, response->headers->response_code());
14592
14593 trans.reset();
14594 session->CloseAllConnections();
14595}
14596
[email protected]89ceba9a2009-03-21 03:46:0614597} // namespace net