blob: 27eaad875d2fa44d20da0c560288cae95d50d74e [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_14,
434 kProtoHTTP2));
[email protected]23e482282013-06-14 16:08:02435
[email protected]448d4ca52012-03-04 04:12:23436namespace {
437
[email protected]1826a402014-01-08 15:40:48438class BeforeNetworkStartHandler {
439 public:
440 explicit BeforeNetworkStartHandler(bool defer)
441 : defer_on_before_network_start_(defer),
442 observed_before_network_start_(false) {}
443
444 void OnBeforeNetworkStart(bool* defer) {
445 *defer = defer_on_before_network_start_;
446 observed_before_network_start_ = true;
447 }
448
449 bool observed_before_network_start() const {
450 return observed_before_network_start_;
451 }
452
453 private:
454 const bool defer_on_before_network_start_;
455 bool observed_before_network_start_;
456
457 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
458};
459
[email protected]597a1ab2014-06-26 08:12:27460class BeforeProxyHeadersSentHandler {
461 public:
462 BeforeProxyHeadersSentHandler()
463 : observed_before_proxy_headers_sent_(false) {}
464
[email protected]1252d42f2014-07-01 21:20:20465 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
466 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27467 observed_before_proxy_headers_sent_ = true;
468 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
469 }
470
471 bool observed_before_proxy_headers_sent() const {
472 return observed_before_proxy_headers_sent_;
473 }
474
475 std::string observed_proxy_server_uri() const {
476 return observed_proxy_server_uri_;
477 }
478
479 private:
480 bool observed_before_proxy_headers_sent_;
481 std::string observed_proxy_server_uri_;
482
483 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
484};
485
[email protected]15a5ccf82008-10-23 19:57:43486// Fill |str| with a long header list that consumes >= |size| bytes.
487void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51488 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19489 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
490 const int sizeof_row = strlen(row);
491 const int num_rows = static_cast<int>(
492 ceil(static_cast<float>(size) / sizeof_row));
493 const int sizeof_data = num_rows * sizeof_row;
494 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43495 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51496
[email protected]4ddaf2502008-10-23 18:26:19497 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43498 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19499}
500
thakis84dff942015-07-28 20:47:38501#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29502// Alternative functions that eliminate randomness and dependency on the local
503// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20504void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29505 static const uint8 bytes[] = {
506 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
507 };
508 static size_t current_byte = 0;
509 for (size_t i = 0; i < n; ++i) {
510 output[i] = bytes[current_byte++];
511 current_byte %= arraysize(bytes);
512 }
513}
514
[email protected]fe2bc6a2009-03-23 16:52:20515void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29516 static const uint8 bytes[] = {
517 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
518 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
519 };
520 static size_t current_byte = 0;
521 for (size_t i = 0; i < n; ++i) {
522 output[i] = bytes[current_byte++];
523 current_byte %= arraysize(bytes);
524 }
525}
526
[email protected]fe2bc6a2009-03-23 16:52:20527std::string MockGetHostName() {
528 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29529}
thakis84dff942015-07-28 20:47:38530#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29531
[email protected]e60e47a2010-07-14 03:37:18532template<typename ParentPool>
533class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31534 public:
[email protected]9e1bdd32011-02-03 21:48:34535 CaptureGroupNameSocketPool(HostResolver* host_resolver,
536 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18537
[email protected]d80a4322009-08-14 07:07:49538 const std::string last_group_name_received() const {
539 return last_group_name_;
540 }
541
dmichaeld6e570d2014-12-18 22:30:57542 int RequestSocket(const std::string& group_name,
543 const void* socket_params,
544 RequestPriority priority,
545 ClientSocketHandle* handle,
546 const CompletionCallback& callback,
547 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31548 last_group_name_ = group_name;
549 return ERR_IO_PENDING;
550 }
dmichaeld6e570d2014-12-18 22:30:57551 void CancelRequest(const std::string& group_name,
552 ClientSocketHandle* handle) override {}
553 void ReleaseSocket(const std::string& group_name,
554 scoped_ptr<StreamSocket> socket,
555 int id) override {}
556 void CloseIdleSockets() override {}
557 int IdleSocketCount() const override { return 0; }
558 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31559 return 0;
560 }
dmichaeld6e570d2014-12-18 22:30:57561 LoadState GetLoadState(const std::string& group_name,
562 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31563 return LOAD_STATE_IDLE;
564 }
dmichaeld6e570d2014-12-18 22:30:57565 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26566 return base::TimeDelta();
567 }
[email protected]d80a4322009-08-14 07:07:49568
569 private:
[email protected]04e5be32009-06-26 20:00:31570 std::string last_group_name_;
571};
572
[email protected]ab739042011-04-07 15:22:28573typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
574CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13575typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
576CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06577typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11578CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18579typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
580CaptureGroupNameSSLSocketPool;
581
rkaplowd90695c2015-03-25 22:12:41582template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18583CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34584 HostResolver* host_resolver,
585 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41586 : ParentPool(0, 0, host_resolver, NULL, NULL) {
587}
[email protected]e60e47a2010-07-14 03:37:18588
hashimoto0d3e4fb2015-01-09 05:02:50589template <>
[email protected]2df19bb2010-08-25 20:13:46590CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21591 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34592 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41593 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50594}
[email protected]2df19bb2010-08-25 20:13:46595
[email protected]007b3f82013-04-09 08:46:45596template <>
[email protected]e60e47a2010-07-14 03:37:18597CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21598 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34599 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45600 : SSLClientSocketPool(0,
601 0,
[email protected]007b3f82013-04-09 08:46:45602 cert_verifier,
603 NULL,
604 NULL,
[email protected]284303b62013-11-28 15:11:54605 NULL,
eranm6571b2b2014-12-03 15:53:23606 NULL,
[email protected]007b3f82013-04-09 08:46:45607 std::string(),
608 NULL,
609 NULL,
610 NULL,
611 NULL,
612 NULL,
[email protected]8e458552014-08-05 00:02:15613 NULL) {
614}
[email protected]2227c692010-05-04 15:36:11615
[email protected]231d5a32008-09-13 00:45:27616//-----------------------------------------------------------------------------
617
[email protected]79cb5c12011-09-12 13:12:04618// Helper functions for validating that AuthChallengeInfo's are correctly
619// configured for common cases.
620bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
621 if (!auth_challenge)
622 return false;
623 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23624 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04625 EXPECT_EQ("MyRealm1", auth_challenge->realm);
626 EXPECT_EQ("basic", auth_challenge->scheme);
627 return true;
628}
629
630bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
631 if (!auth_challenge)
632 return false;
633 EXPECT_TRUE(auth_challenge->is_proxy);
634 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
635 EXPECT_EQ("MyRealm1", auth_challenge->realm);
636 EXPECT_EQ("basic", auth_challenge->scheme);
637 return true;
638}
639
640bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
641 if (!auth_challenge)
642 return false;
643 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23644 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04645 EXPECT_EQ("digestive", auth_challenge->realm);
646 EXPECT_EQ("digest", auth_challenge->scheme);
647 return true;
648}
649
thakis84dff942015-07-28 20:47:38650#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04651bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
652 if (!auth_challenge)
653 return false;
654 EXPECT_FALSE(auth_challenge->is_proxy);
655 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
656 EXPECT_EQ(std::string(), auth_challenge->realm);
657 EXPECT_EQ("ntlm", auth_challenge->scheme);
658 return true;
659}
thakis84dff942015-07-28 20:47:38660#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04661
[email protected]448d4ca52012-03-04 04:12:23662} // namespace
663
[email protected]23e482282013-06-14 16:08:02664TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07665 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40666 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41667 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27668}
669
[email protected]23e482282013-06-14 16:08:02670TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27671 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35672 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
673 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06674 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27675 };
[email protected]31a2bfe2010-02-09 08:03:39676 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
677 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42678 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27679 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
680 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19681 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
682 EXPECT_EQ(reads_size, out.totalReceivedBytes);
ttuttle1f2d7e92015-04-28 16:17:47683 EXPECT_EQ(0u, out.connection_attempts.size());
[email protected]231d5a32008-09-13 00:45:27684}
685
686// Response with no status line.
[email protected]23e482282013-06-14 16:08:02687TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27688 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35689 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06690 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27691 };
[email protected]31a2bfe2010-02-09 08:03:39692 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
693 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42694 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27695 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
696 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19697 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
698 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27699}
700
701// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02702TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27703 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35704 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06705 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27706 };
[email protected]31a2bfe2010-02-09 08:03:39707 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
708 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42709 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27710 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
711 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19712 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
713 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27714}
715
716// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02717TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27718 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35719 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06720 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27721 };
[email protected]31a2bfe2010-02-09 08:03:39722 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
723 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42724 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27725 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
726 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19727 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
728 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27729}
730
731// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02732TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27733 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35734 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06735 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27736 };
[email protected]31a2bfe2010-02-09 08:03:39737 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
738 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42739 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25740 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
741 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19742 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
743 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27744}
745
746// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02747TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27748 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35749 MockRead("\n"),
750 MockRead("\n"),
751 MockRead("Q"),
752 MockRead("J"),
753 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06754 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27755 };
[email protected]31a2bfe2010-02-09 08:03:39756 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
757 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42758 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27759 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
760 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19761 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
762 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27763}
764
765// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02766TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27767 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35768 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06769 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27770 };
[email protected]31a2bfe2010-02-09 08:03:39771 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
772 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42773 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27774 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
775 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19776 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
777 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52778}
779
[email protected]f9d44aa2008-09-23 23:57:17780// Simulate a 204 response, lacking a Content-Length header, sent over a
781// persistent connection. The response should still terminate since a 204
782// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02783TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19784 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17785 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35786 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19787 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06788 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17789 };
[email protected]31a2bfe2010-02-09 08:03:39790 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
791 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42792 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17793 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
794 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19795 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
796 int64 response_size = reads_size - strlen(junk);
797 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17798}
799
[email protected]0877e3d2009-10-17 22:29:57800// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02801TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19802 std::string final_chunk = "0\r\n\r\n";
803 std::string extra_data = "HTTP/1.1 200 OK\r\n";
804 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57805 MockRead data_reads[] = {
806 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
807 MockRead("5\r\nHello\r\n"),
808 MockRead("1\r\n"),
809 MockRead(" \r\n"),
810 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19811 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06812 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57813 };
[email protected]31a2bfe2010-02-09 08:03:39814 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
815 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57816 EXPECT_EQ(OK, out.rv);
817 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
818 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19819 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
820 int64 response_size = reads_size - extra_data.size();
821 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57822}
823
[email protected]9fe44f52010-09-23 18:36:00824// Next tests deal with http://crbug.com/56344.
825
[email protected]23e482282013-06-14 16:08:02826TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00827 MultipleContentLengthHeadersNoTransferEncoding) {
828 MockRead data_reads[] = {
829 MockRead("HTTP/1.1 200 OK\r\n"),
830 MockRead("Content-Length: 10\r\n"),
831 MockRead("Content-Length: 5\r\n\r\n"),
832 };
833 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
834 arraysize(data_reads));
835 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
836}
837
[email protected]23e482282013-06-14 16:08:02838TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04839 DuplicateContentLengthHeadersNoTransferEncoding) {
840 MockRead data_reads[] = {
841 MockRead("HTTP/1.1 200 OK\r\n"),
842 MockRead("Content-Length: 5\r\n"),
843 MockRead("Content-Length: 5\r\n\r\n"),
844 MockRead("Hello"),
845 };
846 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
847 arraysize(data_reads));
848 EXPECT_EQ(OK, out.rv);
849 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
850 EXPECT_EQ("Hello", out.response_data);
851}
852
[email protected]23e482282013-06-14 16:08:02853TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04854 ComplexContentLengthHeadersNoTransferEncoding) {
855 // More than 2 dupes.
856 {
857 MockRead data_reads[] = {
858 MockRead("HTTP/1.1 200 OK\r\n"),
859 MockRead("Content-Length: 5\r\n"),
860 MockRead("Content-Length: 5\r\n"),
861 MockRead("Content-Length: 5\r\n\r\n"),
862 MockRead("Hello"),
863 };
864 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
865 arraysize(data_reads));
866 EXPECT_EQ(OK, out.rv);
867 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
868 EXPECT_EQ("Hello", out.response_data);
869 }
870 // HTTP/1.0
871 {
872 MockRead data_reads[] = {
873 MockRead("HTTP/1.0 200 OK\r\n"),
874 MockRead("Content-Length: 5\r\n"),
875 MockRead("Content-Length: 5\r\n"),
876 MockRead("Content-Length: 5\r\n\r\n"),
877 MockRead("Hello"),
878 };
879 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
880 arraysize(data_reads));
881 EXPECT_EQ(OK, out.rv);
882 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
883 EXPECT_EQ("Hello", out.response_data);
884 }
885 // 2 dupes and one mismatched.
886 {
887 MockRead data_reads[] = {
888 MockRead("HTTP/1.1 200 OK\r\n"),
889 MockRead("Content-Length: 10\r\n"),
890 MockRead("Content-Length: 10\r\n"),
891 MockRead("Content-Length: 5\r\n\r\n"),
892 };
893 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
894 arraysize(data_reads));
895 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
896 }
897}
898
[email protected]23e482282013-06-14 16:08:02899TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00900 MultipleContentLengthHeadersTransferEncoding) {
901 MockRead data_reads[] = {
902 MockRead("HTTP/1.1 200 OK\r\n"),
903 MockRead("Content-Length: 666\r\n"),
904 MockRead("Content-Length: 1337\r\n"),
905 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
906 MockRead("5\r\nHello\r\n"),
907 MockRead("1\r\n"),
908 MockRead(" \r\n"),
909 MockRead("5\r\nworld\r\n"),
910 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06911 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00912 };
913 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
914 arraysize(data_reads));
915 EXPECT_EQ(OK, out.rv);
916 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
917 EXPECT_EQ("Hello world", out.response_data);
918}
919
[email protected]1628fe92011-10-04 23:04:55920// Next tests deal with http://crbug.com/98895.
921
922// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02923TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55924 MockRead data_reads[] = {
925 MockRead("HTTP/1.1 200 OK\r\n"),
926 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
927 MockRead("Content-Length: 5\r\n\r\n"),
928 MockRead("Hello"),
929 };
930 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
931 arraysize(data_reads));
932 EXPECT_EQ(OK, out.rv);
933 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
934 EXPECT_EQ("Hello", out.response_data);
935}
936
[email protected]54a9c6e52012-03-21 20:10:59937// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02938TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59939 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55940 MockRead data_reads[] = {
941 MockRead("HTTP/1.1 200 OK\r\n"),
942 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
943 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
944 MockRead("Content-Length: 5\r\n\r\n"),
945 MockRead("Hello"),
946 };
947 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
948 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59949 EXPECT_EQ(OK, out.rv);
950 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
951 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55952}
953
954// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02955TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55956 MockRead data_reads[] = {
957 MockRead("HTTP/1.1 200 OK\r\n"),
958 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
959 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
960 MockRead("Content-Length: 5\r\n\r\n"),
961 MockRead("Hello"),
962 };
963 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
964 arraysize(data_reads));
965 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
966}
967
[email protected]54a9c6e52012-03-21 20:10:59968// Checks that two identical Location headers result in no error.
969// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02970TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55971 MockRead data_reads[] = {
972 MockRead("HTTP/1.1 302 Redirect\r\n"),
973 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59974 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55975 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06976 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55977 };
978
979 HttpRequestInfo request;
980 request.method = "GET";
981 request.url = GURL("http://redirect.com/");
982 request.load_flags = 0;
983
[email protected]3fe8d2f82013-10-17 08:56:07984 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55985 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41986 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:55987
988 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07989 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55990
[email protected]49639fa2011-12-20 23:22:41991 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55992
[email protected]49639fa2011-12-20 23:22:41993 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55994 EXPECT_EQ(ERR_IO_PENDING, rv);
995
996 EXPECT_EQ(OK, callback.WaitForResult());
997
998 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50999 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:551000 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1001 std::string url;
1002 EXPECT_TRUE(response->headers->IsRedirect(&url));
1003 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151004 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551005}
1006
[email protected]1628fe92011-10-04 23:04:551007// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021008TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551009 MockRead data_reads[] = {
1010 MockRead("HTTP/1.1 302 Redirect\r\n"),
1011 MockRead("Location: http://good.com/\r\n"),
1012 MockRead("Location: http://evil.com/\r\n"),
1013 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061014 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551015 };
1016 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1017 arraysize(data_reads));
1018 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1019}
1020
[email protected]ef0faf2e72009-03-05 23:27:231021// Do a request using the HEAD method. Verify that we don't try to read the
1022// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021023TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421024 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231025 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231026 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231027 request.load_flags = 0;
1028
[email protected]3fe8d2f82013-10-17 08:56:071029 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271030 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411031 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271032 BeforeProxyHeadersSentHandler proxy_headers_handler;
1033 trans->SetBeforeProxyHeadersSentCallback(
1034 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1035 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271036
[email protected]ef0faf2e72009-03-05 23:27:231037 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131038 MockWrite("HEAD / HTTP/1.1\r\n"
1039 "Host: www.example.org\r\n"
1040 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231041 };
1042 MockRead data_reads1[] = {
1043 MockRead("HTTP/1.1 404 Not Found\r\n"),
1044 MockRead("Server: Blah\r\n"),
1045 MockRead("Content-Length: 1234\r\n\r\n"),
1046
1047 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061048 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231049 };
1050
[email protected]31a2bfe2010-02-09 08:03:391051 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1052 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071053 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231054
[email protected]49639fa2011-12-20 23:22:411055 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231056
[email protected]49639fa2011-12-20 23:22:411057 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421058 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231059
1060 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421061 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231062
[email protected]1c773ea12009-04-28 19:58:421063 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501064 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231065
1066 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501067 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231068 EXPECT_EQ(1234, response->headers->GetContentLength());
1069 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151070 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271071 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231072
1073 std::string server_header;
1074 void* iter = NULL;
1075 bool has_server_header = response->headers->EnumerateHeader(
1076 &iter, "Server", &server_header);
1077 EXPECT_TRUE(has_server_header);
1078 EXPECT_EQ("Blah", server_header);
1079
1080 // Reading should give EOF right away, since there is no message body
1081 // (despite non-zero content-length).
1082 std::string response_data;
1083 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421084 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231085 EXPECT_EQ("", response_data);
1086}
1087
[email protected]23e482282013-06-14 16:08:021088TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071089 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521090
1091 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351092 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1093 MockRead("hello"),
1094 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1095 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061096 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521097 };
[email protected]31a2bfe2010-02-09 08:03:391098 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071099 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521100
[email protected]0b0bf032010-09-21 18:08:501101 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521102 "hello", "world"
1103 };
1104
1105 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421106 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521107 request.method = "GET";
bncce36dca22015-04-21 22:11:231108 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521109 request.load_flags = 0;
1110
[email protected]262eec82013-03-19 21:01:361111 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501112 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271113
[email protected]49639fa2011-12-20 23:22:411114 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521115
[email protected]49639fa2011-12-20 23:22:411116 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421117 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521118
1119 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421120 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521121
[email protected]1c773ea12009-04-28 19:58:421122 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501123 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521124
[email protected]90499482013-06-01 00:39:501125 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251126 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151127 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521128
1129 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571130 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421131 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251132 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521133 }
1134}
1135
[email protected]23e482282013-06-14 16:08:021136TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061137 ScopedVector<UploadElementReader> element_readers;
1138 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071139 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271140
[email protected]1c773ea12009-04-28 19:58:421141 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521142 request.method = "POST";
1143 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271144 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521145 request.load_flags = 0;
1146
[email protected]3fe8d2f82013-10-17 08:56:071147 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271148 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411149 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271150
initial.commit586acc5fe2008-07-26 22:42:521151 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351152 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1153 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1154 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061155 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521156 };
[email protected]31a2bfe2010-02-09 08:03:391157 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071158 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521159
[email protected]49639fa2011-12-20 23:22:411160 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521161
[email protected]49639fa2011-12-20 23:22:411162 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421163 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521164
1165 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421166 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521167
[email protected]1c773ea12009-04-28 19:58:421168 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501169 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521170
[email protected]90499482013-06-01 00:39:501171 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251172 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521173
1174 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571175 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421176 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251177 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521178}
1179
[email protected]3a2d3662009-03-27 03:49:141180// This test is almost the same as Ignores100 above, but the response contains
1181// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571182// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021183TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421184 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141185 request.method = "GET";
1186 request.url = GURL("http://www.foo.com/");
1187 request.load_flags = 0;
1188
[email protected]3fe8d2f82013-10-17 08:56:071189 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271190 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271192
[email protected]3a2d3662009-03-27 03:49:141193 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571194 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1195 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141196 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061197 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141198 };
[email protected]31a2bfe2010-02-09 08:03:391199 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071200 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141201
[email protected]49639fa2011-12-20 23:22:411202 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141203
[email protected]49639fa2011-12-20 23:22:411204 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421205 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141206
1207 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421208 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141209
[email protected]1c773ea12009-04-28 19:58:421210 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501211 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141212
[email protected]90499482013-06-01 00:39:501213 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141214 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1215
1216 std::string response_data;
1217 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421218 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141219 EXPECT_EQ("hello world", response_data);
1220}
1221
[email protected]23e482282013-06-14 16:08:021222TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081223 HttpRequestInfo request;
1224 request.method = "POST";
1225 request.url = GURL("http://www.foo.com/");
1226 request.load_flags = 0;
1227
1228 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1229 scoped_ptr<HttpTransaction> trans(
1230 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1231
1232 MockRead data_reads[] = {
1233 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1234 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381235 };
zmo9528c9f42015-08-04 22:12:081236 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1237 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381238
zmo9528c9f42015-08-04 22:12:081239 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381240
zmo9528c9f42015-08-04 22:12:081241 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1242 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381243
zmo9528c9f42015-08-04 22:12:081244 rv = callback.WaitForResult();
1245 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381246
zmo9528c9f42015-08-04 22:12:081247 std::string response_data;
1248 rv = ReadTransaction(trans.get(), &response_data);
1249 EXPECT_EQ(OK, rv);
1250 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381251}
1252
[email protected]23e482282013-06-14 16:08:021253TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381254 HttpRequestInfo request;
1255 request.method = "POST";
1256 request.url = GURL("http://www.foo.com/");
1257 request.load_flags = 0;
1258
[email protected]3fe8d2f82013-10-17 08:56:071259 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271260 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411261 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271262
[email protected]ee9410e72010-01-07 01:42:381263 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061264 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381265 };
[email protected]31a2bfe2010-02-09 08:03:391266 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071267 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381268
[email protected]49639fa2011-12-20 23:22:411269 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381270
[email protected]49639fa2011-12-20 23:22:411271 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381272 EXPECT_EQ(ERR_IO_PENDING, rv);
1273
1274 rv = callback.WaitForResult();
1275 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1276}
1277
[email protected]23e482282013-06-14 16:08:021278void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511279 const MockWrite* write_failure,
1280 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421281 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521282 request.method = "GET";
1283 request.url = GURL("http://www.foo.com/");
1284 request.load_flags = 0;
1285
vishal.b62985ca92015-04-17 08:45:511286 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071287 session_deps_.net_log = &net_log;
1288 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271289
[email protected]202965992011-12-07 23:04:511290 // Written data for successfully sending both requests.
1291 MockWrite data1_writes[] = {
1292 MockWrite("GET / HTTP/1.1\r\n"
1293 "Host: www.foo.com\r\n"
1294 "Connection: keep-alive\r\n\r\n"),
1295 MockWrite("GET / HTTP/1.1\r\n"
1296 "Host: www.foo.com\r\n"
1297 "Connection: keep-alive\r\n\r\n")
1298 };
1299
1300 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521301 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351302 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1303 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061304 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521305 };
[email protected]202965992011-12-07 23:04:511306
1307 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491308 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511309 data1_writes[1] = *write_failure;
1310 } else {
1311 ASSERT_TRUE(read_failure);
1312 data1_reads[2] = *read_failure;
1313 }
1314
1315 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1316 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071317 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521318
1319 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351320 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1321 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061322 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521323 };
[email protected]31a2bfe2010-02-09 08:03:391324 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071325 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521326
thestig9d3bb0c2015-01-24 00:49:511327 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521328 "hello", "world"
1329 };
1330
[email protected]58e32bb2013-01-21 18:23:251331 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521332 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411333 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521334
[email protected]262eec82013-03-19 21:01:361335 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501336 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521337
[email protected]49639fa2011-12-20 23:22:411338 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421339 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521340
1341 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421342 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521343
[email protected]58e32bb2013-01-21 18:23:251344 LoadTimingInfo load_timing_info;
1345 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1346 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1347 if (i == 0) {
1348 first_socket_log_id = load_timing_info.socket_log_id;
1349 } else {
1350 // The second request should be using a new socket.
1351 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1352 }
1353
[email protected]1c773ea12009-04-28 19:58:421354 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501355 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521356
[email protected]90499482013-06-01 00:39:501357 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251358 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521359
1360 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571361 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421362 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251363 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521364 }
1365}
[email protected]3d2a59b2008-09-26 19:44:251366
[email protected]a34f61ee2014-03-18 20:59:491367void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1368 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101369 const MockRead* read_failure,
1370 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491371 HttpRequestInfo request;
1372 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101373 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491374 request.load_flags = 0;
1375
vishal.b62985ca92015-04-17 08:45:511376 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491377 session_deps_.net_log = &net_log;
1378 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1379
[email protected]09356c652014-03-25 15:36:101380 SSLSocketDataProvider ssl1(ASYNC, OK);
1381 SSLSocketDataProvider ssl2(ASYNC, OK);
1382 if (use_spdy) {
1383 ssl1.SetNextProto(GetParam());
1384 ssl2.SetNextProto(GetParam());
1385 }
1386 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1387 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491388
[email protected]09356c652014-03-25 15:36:101389 // SPDY versions of the request and response.
1390 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1391 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1392 scoped_ptr<SpdyFrame> spdy_response(
1393 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1394 scoped_ptr<SpdyFrame> spdy_data(
1395 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491396
[email protected]09356c652014-03-25 15:36:101397 // HTTP/1.1 versions of the request and response.
1398 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1399 "Host: www.foo.com\r\n"
1400 "Connection: keep-alive\r\n\r\n";
1401 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1402 const char kHttpData[] = "hello";
1403
1404 std::vector<MockRead> data1_reads;
1405 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491406 if (write_failure) {
1407 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101408 data1_writes.push_back(*write_failure);
1409 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491410 } else {
1411 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101412 if (use_spdy) {
1413 data1_writes.push_back(CreateMockWrite(*spdy_request));
1414 } else {
1415 data1_writes.push_back(MockWrite(kHttpRequest));
1416 }
1417 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491418 }
1419
[email protected]09356c652014-03-25 15:36:101420 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1421 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491422 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1423
[email protected]09356c652014-03-25 15:36:101424 std::vector<MockRead> data2_reads;
1425 std::vector<MockWrite> data2_writes;
1426
1427 if (use_spdy) {
1428 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1429
1430 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1431 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1432 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1433 } else {
1434 data2_writes.push_back(
1435 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1436
1437 data2_reads.push_back(
1438 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1439 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1440 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1441 }
rch8e6c6c42015-05-01 14:05:131442 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1443 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491444 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1445
1446 // Preconnect a socket.
ttuttle859dc7a2015-04-23 19:42:291447 SSLConfig ssl_config;
[email protected]a34f61ee2014-03-18 20:59:491448 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231449 session->GetNextProtos(&ssl_config.next_protos);
mmenked1205bd3972015-07-15 22:26:351450 session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
1451 ssl_config);
[email protected]a34f61ee2014-03-18 20:59:491452 // Wait for the preconnect to complete.
1453 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1454 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101455 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491456
1457 // Make the request.
1458 TestCompletionCallback callback;
1459
1460 scoped_ptr<HttpTransaction> trans(
1461 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1462
1463 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1464 EXPECT_EQ(ERR_IO_PENDING, rv);
1465
1466 rv = callback.WaitForResult();
1467 EXPECT_EQ(OK, rv);
1468
1469 LoadTimingInfo load_timing_info;
1470 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101471 TestLoadTimingNotReused(
1472 load_timing_info,
1473 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491474
1475 const HttpResponseInfo* response = trans->GetResponseInfo();
1476 ASSERT_TRUE(response != NULL);
1477
1478 EXPECT_TRUE(response->headers.get() != NULL);
1479 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1480
1481 std::string response_data;
1482 rv = ReadTransaction(trans.get(), &response_data);
1483 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101484 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491485}
1486
[email protected]23e482282013-06-14 16:08:021487TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231488 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061489 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511490 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1491}
1492
[email protected]23e482282013-06-14 16:08:021493TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061494 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511495 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251496}
1497
[email protected]23e482282013-06-14 16:08:021498TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061499 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511500 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251501}
1502
[email protected]d58ceea82014-06-04 10:55:541503// Make sure that on a 408 response (Request Timeout), the request is retried,
1504// if the socket was a reused keep alive socket.
1505TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1506 MockRead read_failure(SYNCHRONOUS,
1507 "HTTP/1.1 408 Request Timeout\r\n"
1508 "Connection: Keep-Alive\r\n"
1509 "Content-Length: 6\r\n\r\n"
1510 "Pickle");
1511 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1512}
1513
[email protected]a34f61ee2014-03-18 20:59:491514TEST_P(HttpNetworkTransactionTest,
1515 PreconnectErrorNotConnectedOnWrite) {
1516 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101517 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491518}
1519
1520TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1521 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101522 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491523}
1524
1525TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1526 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101527 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1528}
1529
1530TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1531 MockRead read_failure(ASYNC, OK); // EOF
1532 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1533}
1534
[email protected]d58ceea82014-06-04 10:55:541535// Make sure that on a 408 response (Request Timeout), the request is retried,
1536// if the socket was a preconnected (UNUSED_IDLE) socket.
1537TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1538 MockRead read_failure(SYNCHRONOUS,
1539 "HTTP/1.1 408 Request Timeout\r\n"
1540 "Connection: Keep-Alive\r\n"
1541 "Content-Length: 6\r\n\r\n"
1542 "Pickle");
1543 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1544 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1545}
1546
[email protected]09356c652014-03-25 15:36:101547TEST_P(HttpNetworkTransactionTest,
1548 SpdyPreconnectErrorNotConnectedOnWrite) {
1549 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1550 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1551}
1552
1553TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1554 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1555 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1556}
1557
1558TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1559 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1560 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1561}
1562
1563TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1564 MockRead read_failure(ASYNC, OK); // EOF
1565 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491566}
1567
[email protected]23e482282013-06-14 16:08:021568TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421569 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251570 request.method = "GET";
bncce36dca22015-04-21 22:11:231571 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251572 request.load_flags = 0;
1573
[email protected]3fe8d2f82013-10-17 08:56:071574 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271575 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411576 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271577
[email protected]3d2a59b2008-09-26 19:44:251578 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061579 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351580 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1581 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061582 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251583 };
[email protected]31a2bfe2010-02-09 08:03:391584 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071585 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251586
[email protected]49639fa2011-12-20 23:22:411587 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251588
[email protected]49639fa2011-12-20 23:22:411589 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421590 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251591
1592 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421593 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251594}
1595
1596// What do various browsers do when the server closes a non-keepalive
1597// connection without sending any response header or body?
1598//
1599// IE7: error page
1600// Safari 3.1.2 (Windows): error page
1601// Firefox 3.0.1: blank page
1602// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421603// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1604// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021605TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251606 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061607 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351608 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1609 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061610 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251611 };
[email protected]31a2bfe2010-02-09 08:03:391612 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1613 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421614 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251615}
[email protected]038e9a32008-10-08 22:40:161616
[email protected]1826a402014-01-08 15:40:481617// Test that network access can be deferred and resumed.
1618TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1619 HttpRequestInfo request;
1620 request.method = "GET";
bncce36dca22015-04-21 22:11:231621 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481622 request.load_flags = 0;
1623
1624 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1625 scoped_ptr<HttpTransaction> trans(
1626 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1627
1628 // Defer on OnBeforeNetworkStart.
1629 BeforeNetworkStartHandler net_start_handler(true); // defer
1630 trans->SetBeforeNetworkStartCallback(
1631 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1632 base::Unretained(&net_start_handler)));
1633
1634 MockRead data_reads[] = {
1635 MockRead("HTTP/1.0 200 OK\r\n"),
1636 MockRead("Content-Length: 5\r\n\r\n"),
1637 MockRead("hello"),
1638 MockRead(SYNCHRONOUS, 0),
1639 };
1640 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1641 session_deps_.socket_factory->AddSocketDataProvider(&data);
1642
1643 TestCompletionCallback callback;
1644
1645 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1646 EXPECT_EQ(ERR_IO_PENDING, rv);
1647 base::MessageLoop::current()->RunUntilIdle();
1648
1649 // Should have deferred for network start.
1650 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1651 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481652
1653 trans->ResumeNetworkStart();
1654 rv = callback.WaitForResult();
1655 EXPECT_EQ(OK, rv);
1656 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1657
1658 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1659 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1660 if (rv == ERR_IO_PENDING)
1661 rv = callback.WaitForResult();
1662 EXPECT_EQ(5, rv);
1663 trans.reset();
1664}
1665
1666// Test that network use can be deferred and canceled.
1667TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1668 HttpRequestInfo request;
1669 request.method = "GET";
bncce36dca22015-04-21 22:11:231670 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481671 request.load_flags = 0;
1672
1673 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1674 scoped_ptr<HttpTransaction> trans(
1675 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1676
1677 // Defer on OnBeforeNetworkStart.
1678 BeforeNetworkStartHandler net_start_handler(true); // defer
1679 trans->SetBeforeNetworkStartCallback(
1680 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1681 base::Unretained(&net_start_handler)));
1682
1683 TestCompletionCallback callback;
1684
1685 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1686 EXPECT_EQ(ERR_IO_PENDING, rv);
1687 base::MessageLoop::current()->RunUntilIdle();
1688
1689 // Should have deferred for network start.
1690 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1691 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481692}
1693
[email protected]7a5378b2012-11-04 03:25:171694// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1695// tests. There was a bug causing HttpNetworkTransaction to hang in the
1696// destructor in such situations.
1697// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021698TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171699 HttpRequestInfo request;
1700 request.method = "GET";
bncce36dca22015-04-21 22:11:231701 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171702 request.load_flags = 0;
1703
[email protected]bb88e1d32013-05-03 23:11:071704 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361705 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501706 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171707
1708 MockRead data_reads[] = {
1709 MockRead("HTTP/1.0 200 OK\r\n"),
1710 MockRead("Connection: keep-alive\r\n"),
1711 MockRead("Content-Length: 100\r\n\r\n"),
1712 MockRead("hello"),
1713 MockRead(SYNCHRONOUS, 0),
1714 };
1715 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071716 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171717
1718 TestCompletionCallback callback;
1719
1720 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1721 EXPECT_EQ(ERR_IO_PENDING, rv);
1722
1723 rv = callback.WaitForResult();
1724 EXPECT_EQ(OK, rv);
1725
1726 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501727 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171728 if (rv == ERR_IO_PENDING)
1729 rv = callback.WaitForResult();
1730 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501731 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171732 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1733
1734 trans.reset();
[email protected]2da659e2013-05-23 20:51:341735 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171736 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1737}
1738
[email protected]23e482282013-06-14 16:08:021739TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171740 HttpRequestInfo request;
1741 request.method = "GET";
bncce36dca22015-04-21 22:11:231742 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171743 request.load_flags = 0;
1744
[email protected]bb88e1d32013-05-03 23:11:071745 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361746 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501747 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171748
1749 MockRead data_reads[] = {
1750 MockRead("HTTP/1.0 200 OK\r\n"),
1751 MockRead("Connection: keep-alive\r\n"),
1752 MockRead("Content-Length: 100\r\n\r\n"),
1753 MockRead(SYNCHRONOUS, 0),
1754 };
1755 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071756 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171757
1758 TestCompletionCallback callback;
1759
1760 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1761 EXPECT_EQ(ERR_IO_PENDING, rv);
1762
1763 rv = callback.WaitForResult();
1764 EXPECT_EQ(OK, rv);
1765
1766 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501767 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171768 if (rv == ERR_IO_PENDING)
1769 rv = callback.WaitForResult();
1770 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1771
1772 trans.reset();
[email protected]2da659e2013-05-23 20:51:341773 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171774 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1775}
1776
[email protected]0b0bf032010-09-21 18:08:501777// Test that we correctly reuse a keep-alive connection after not explicitly
1778// reading the body.
[email protected]23e482282013-06-14 16:08:021779TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131780 HttpRequestInfo request;
1781 request.method = "GET";
1782 request.url = GURL("http://www.foo.com/");
1783 request.load_flags = 0;
1784
vishal.b62985ca92015-04-17 08:45:511785 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071786 session_deps_.net_log = &net_log;
1787 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271788
[email protected]0b0bf032010-09-21 18:08:501789 // Note that because all these reads happen in the same
1790 // StaticSocketDataProvider, it shows that the same socket is being reused for
1791 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131792 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501793 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1794 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131795 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501796 MockRead("HTTP/1.1 302 Found\r\n"
1797 "Content-Length: 0\r\n\r\n"),
1798 MockRead("HTTP/1.1 302 Found\r\n"
1799 "Content-Length: 5\r\n\r\n"
1800 "hello"),
1801 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1802 "Content-Length: 0\r\n\r\n"),
1803 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1804 "Content-Length: 5\r\n\r\n"
1805 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131806 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1807 MockRead("hello"),
1808 };
1809 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071810 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131811
1812 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061813 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131814 };
1815 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071816 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131817
[email protected]0b0bf032010-09-21 18:08:501818 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1819 std::string response_lines[kNumUnreadBodies];
1820
[email protected]58e32bb2013-01-21 18:23:251821 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501822 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411823 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131824
[email protected]262eec82013-03-19 21:01:361825 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501826 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131827
[email protected]49639fa2011-12-20 23:22:411828 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131829 EXPECT_EQ(ERR_IO_PENDING, rv);
1830
1831 rv = callback.WaitForResult();
1832 EXPECT_EQ(OK, rv);
1833
[email protected]58e32bb2013-01-21 18:23:251834 LoadTimingInfo load_timing_info;
1835 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1836 if (i == 0) {
1837 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1838 first_socket_log_id = load_timing_info.socket_log_id;
1839 } else {
1840 TestLoadTimingReused(load_timing_info);
1841 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1842 }
1843
[email protected]fc31d6a42010-06-24 18:05:131844 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501845 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131846
[email protected]90499482013-06-01 00:39:501847 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501848 response_lines[i] = response->headers->GetStatusLine();
1849
1850 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131851 }
[email protected]0b0bf032010-09-21 18:08:501852
1853 const char* const kStatusLines[] = {
1854 "HTTP/1.1 204 No Content",
1855 "HTTP/1.1 205 Reset Content",
1856 "HTTP/1.1 304 Not Modified",
1857 "HTTP/1.1 302 Found",
1858 "HTTP/1.1 302 Found",
1859 "HTTP/1.1 301 Moved Permanently",
1860 "HTTP/1.1 301 Moved Permanently",
1861 };
1862
mostynb91e0da982015-01-20 19:17:271863 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1864 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501865
1866 for (int i = 0; i < kNumUnreadBodies; ++i)
1867 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1868
[email protected]49639fa2011-12-20 23:22:411869 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361870 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501871 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411872 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501873 EXPECT_EQ(ERR_IO_PENDING, rv);
1874 rv = callback.WaitForResult();
1875 EXPECT_EQ(OK, rv);
1876 const HttpResponseInfo* response = trans->GetResponseInfo();
1877 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501878 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501879 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1880 std::string response_data;
1881 rv = ReadTransaction(trans.get(), &response_data);
1882 EXPECT_EQ(OK, rv);
1883 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131884}
1885
[email protected]038e9a32008-10-08 22:40:161886// Test the request-challenge-retry sequence for basic auth.
1887// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021888TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421889 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161890 request.method = "GET";
bncce36dca22015-04-21 22:11:231891 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161892 request.load_flags = 0;
1893
vishal.b62985ca92015-04-17 08:45:511894 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071895 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071896 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271897 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411898 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271899
[email protected]f9ee6b52008-11-08 06:46:231900 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231901 MockWrite(
1902 "GET / HTTP/1.1\r\n"
1903 "Host: www.example.org\r\n"
1904 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231905 };
1906
[email protected]038e9a32008-10-08 22:40:161907 MockRead data_reads1[] = {
1908 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1909 // Give a couple authenticate options (only the middle one is actually
1910 // supported).
[email protected]22927ad2009-09-21 19:56:191911 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161912 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1913 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1914 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1915 // Large content-length -- won't matter, as connection will be reset.
1916 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061917 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161918 };
1919
1920 // After calling trans->RestartWithAuth(), this is the request we should
1921 // be issuing -- the final header line contains the credentials.
1922 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231923 MockWrite(
1924 "GET / HTTP/1.1\r\n"
1925 "Host: www.example.org\r\n"
1926 "Connection: keep-alive\r\n"
1927 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161928 };
1929
1930 // Lastly, the server responds with the actual content.
1931 MockRead data_reads2[] = {
1932 MockRead("HTTP/1.0 200 OK\r\n"),
1933 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1934 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061935 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161936 };
1937
[email protected]31a2bfe2010-02-09 08:03:391938 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1939 data_writes1, arraysize(data_writes1));
1940 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1941 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071942 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1943 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161944
[email protected]49639fa2011-12-20 23:22:411945 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161946
[email protected]49639fa2011-12-20 23:22:411947 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421948 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161949
1950 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421951 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161952
[email protected]58e32bb2013-01-21 18:23:251953 LoadTimingInfo load_timing_info1;
1954 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1955 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1956
[email protected]b8015c42013-12-24 15:18:191957 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1958 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1959
[email protected]1c773ea12009-04-28 19:58:421960 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501961 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041962 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161963
[email protected]49639fa2011-12-20 23:22:411964 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161965
[email protected]49639fa2011-12-20 23:22:411966 rv = trans->RestartWithAuth(
1967 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421968 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161969
1970 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421971 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161972
[email protected]58e32bb2013-01-21 18:23:251973 LoadTimingInfo load_timing_info2;
1974 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1975 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1976 // The load timing after restart should have a new socket ID, and times after
1977 // those of the first load timing.
1978 EXPECT_LE(load_timing_info1.receive_headers_end,
1979 load_timing_info2.connect_timing.connect_start);
1980 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1981
[email protected]b8015c42013-12-24 15:18:191982 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1983 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1984
[email protected]038e9a32008-10-08 22:40:161985 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501986 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161987 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1988 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161989}
1990
[email protected]23e482282013-06-14 16:08:021991TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461992 HttpRequestInfo request;
1993 request.method = "GET";
bncce36dca22015-04-21 22:11:231994 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:291995 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:461996
[email protected]3fe8d2f82013-10-17 08:56:071997 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271998 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411999 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272000
[email protected]861fcd52009-08-26 02:33:462001 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232002 MockWrite(
2003 "GET / HTTP/1.1\r\n"
2004 "Host: www.example.org\r\n"
2005 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462006 };
2007
2008 MockRead data_reads[] = {
2009 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2010 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2011 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2012 // Large content-length -- won't matter, as connection will be reset.
2013 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062014 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462015 };
2016
[email protected]31a2bfe2010-02-09 08:03:392017 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2018 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072019 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412020 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462021
[email protected]49639fa2011-12-20 23:22:412022 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462023 EXPECT_EQ(ERR_IO_PENDING, rv);
2024
2025 rv = callback.WaitForResult();
2026 EXPECT_EQ(0, rv);
2027
[email protected]b8015c42013-12-24 15:18:192028 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2029 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2030
[email protected]861fcd52009-08-26 02:33:462031 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502032 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462033 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2034}
2035
[email protected]2d2697f92009-02-18 21:00:322036// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2037// connection.
[email protected]23e482282013-06-14 16:08:022038TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422039 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322040 request.method = "GET";
bncce36dca22015-04-21 22:11:232041 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322042 request.load_flags = 0;
2043
vishal.b62985ca92015-04-17 08:45:512044 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072045 session_deps_.net_log = &log;
2046 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272047
[email protected]2d2697f92009-02-18 21:00:322048 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232049 MockWrite(
2050 "GET / HTTP/1.1\r\n"
2051 "Host: www.example.org\r\n"
2052 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322053
bncce36dca22015-04-21 22:11:232054 // After calling trans->RestartWithAuth(), this is the request we should
2055 // be issuing -- the final header line contains the credentials.
2056 MockWrite(
2057 "GET / HTTP/1.1\r\n"
2058 "Host: www.example.org\r\n"
2059 "Connection: keep-alive\r\n"
2060 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322061 };
2062
2063 MockRead data_reads1[] = {
2064 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2065 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2066 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2067 MockRead("Content-Length: 14\r\n\r\n"),
2068 MockRead("Unauthorized\r\n"),
2069
2070 // Lastly, the server responds with the actual content.
2071 MockRead("HTTP/1.1 200 OK\r\n"),
2072 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502073 MockRead("Content-Length: 5\r\n\r\n"),
2074 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322075 };
2076
[email protected]2d0a4f92011-05-05 16:38:462077 // If there is a regression where we disconnect a Keep-Alive
2078 // connection during an auth roundtrip, we'll end up reading this.
2079 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062080 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462081 };
2082
[email protected]31a2bfe2010-02-09 08:03:392083 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2084 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462085 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2086 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072087 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2088 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322089
[email protected]49639fa2011-12-20 23:22:412090 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322091
[email protected]262eec82013-03-19 21:01:362092 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502093 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412094 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422095 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322096
2097 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422098 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322099
[email protected]58e32bb2013-01-21 18:23:252100 LoadTimingInfo load_timing_info1;
2101 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2102 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2103
[email protected]1c773ea12009-04-28 19:58:422104 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502105 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042106 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322107
[email protected]49639fa2011-12-20 23:22:412108 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322109
[email protected]49639fa2011-12-20 23:22:412110 rv = trans->RestartWithAuth(
2111 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422112 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322113
2114 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422115 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322116
[email protected]58e32bb2013-01-21 18:23:252117 LoadTimingInfo load_timing_info2;
2118 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2119 TestLoadTimingReused(load_timing_info2);
2120 // The load timing after restart should have the same socket ID, and times
2121 // those of the first load timing.
2122 EXPECT_LE(load_timing_info1.receive_headers_end,
2123 load_timing_info2.send_start);
2124 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2125
[email protected]2d2697f92009-02-18 21:00:322126 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502127 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322128 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502129 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192130
2131 std::string response_data;
2132 rv = ReadTransaction(trans.get(), &response_data);
2133 EXPECT_EQ(OK, rv);
2134 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2135 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322136}
2137
2138// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2139// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022140TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422141 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322142 request.method = "GET";
bncce36dca22015-04-21 22:11:232143 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322144 request.load_flags = 0;
2145
[email protected]bb88e1d32013-05-03 23:11:072146 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272147
[email protected]2d2697f92009-02-18 21:00:322148 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232149 MockWrite(
2150 "GET / HTTP/1.1\r\n"
2151 "Host: www.example.org\r\n"
2152 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322153
bncce36dca22015-04-21 22:11:232154 // After calling trans->RestartWithAuth(), this is the request we should
2155 // be issuing -- the final header line contains the credentials.
2156 MockWrite(
2157 "GET / HTTP/1.1\r\n"
2158 "Host: www.example.org\r\n"
2159 "Connection: keep-alive\r\n"
2160 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322161 };
2162
[email protected]2d2697f92009-02-18 21:00:322163 MockRead data_reads1[] = {
2164 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2165 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312166 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322167
2168 // Lastly, the server responds with the actual content.
2169 MockRead("HTTP/1.1 200 OK\r\n"),
2170 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502171 MockRead("Content-Length: 5\r\n\r\n"),
2172 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322173 };
2174
[email protected]2d0a4f92011-05-05 16:38:462175 // An incorrect reconnect would cause this to be read.
2176 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062177 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462178 };
2179
[email protected]31a2bfe2010-02-09 08:03:392180 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2181 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462182 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2183 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072184 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2185 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322186
[email protected]49639fa2011-12-20 23:22:412187 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322188
[email protected]262eec82013-03-19 21:01:362189 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502190 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412191 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422192 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322193
2194 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422195 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322196
[email protected]1c773ea12009-04-28 19:58:422197 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502198 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042199 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322200
[email protected]49639fa2011-12-20 23:22:412201 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322202
[email protected]49639fa2011-12-20 23:22:412203 rv = trans->RestartWithAuth(
2204 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422205 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322206
2207 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422208 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322209
2210 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502211 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322212 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502213 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322214}
2215
2216// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2217// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022218TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422219 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322220 request.method = "GET";
bncce36dca22015-04-21 22:11:232221 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322222 request.load_flags = 0;
2223
[email protected]bb88e1d32013-05-03 23:11:072224 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272225
[email protected]2d2697f92009-02-18 21:00:322226 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232227 MockWrite(
2228 "GET / HTTP/1.1\r\n"
2229 "Host: www.example.org\r\n"
2230 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322231
bncce36dca22015-04-21 22:11:232232 // After calling trans->RestartWithAuth(), this is the request we should
2233 // be issuing -- the final header line contains the credentials.
2234 MockWrite(
2235 "GET / HTTP/1.1\r\n"
2236 "Host: www.example.org\r\n"
2237 "Connection: keep-alive\r\n"
2238 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322239 };
2240
2241 // Respond with 5 kb of response body.
2242 std::string large_body_string("Unauthorized");
2243 large_body_string.append(5 * 1024, ' ');
2244 large_body_string.append("\r\n");
2245
2246 MockRead data_reads1[] = {
2247 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2248 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2249 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2250 // 5134 = 12 + 5 * 1024 + 2
2251 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062252 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322253
2254 // Lastly, the server responds with the actual content.
2255 MockRead("HTTP/1.1 200 OK\r\n"),
2256 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502257 MockRead("Content-Length: 5\r\n\r\n"),
2258 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322259 };
2260
[email protected]2d0a4f92011-05-05 16:38:462261 // An incorrect reconnect would cause this to be read.
2262 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062263 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462264 };
2265
[email protected]31a2bfe2010-02-09 08:03:392266 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2267 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462268 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2269 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072270 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2271 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322272
[email protected]49639fa2011-12-20 23:22:412273 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322274
[email protected]262eec82013-03-19 21:01:362275 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502276 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412277 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422278 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322279
2280 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422281 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322282
[email protected]1c773ea12009-04-28 19:58:422283 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502284 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042285 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322286
[email protected]49639fa2011-12-20 23:22:412287 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322288
[email protected]49639fa2011-12-20 23:22:412289 rv = trans->RestartWithAuth(
2290 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422291 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322292
2293 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422294 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322295
2296 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502297 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322298 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502299 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322300}
2301
2302// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312303// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022304TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312305 HttpRequestInfo request;
2306 request.method = "GET";
bncce36dca22015-04-21 22:11:232307 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312308 request.load_flags = 0;
2309
[email protected]bb88e1d32013-05-03 23:11:072310 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272311
[email protected]11203f012009-11-12 23:02:312312 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232313 MockWrite(
2314 "GET / HTTP/1.1\r\n"
2315 "Host: www.example.org\r\n"
2316 "Connection: keep-alive\r\n\r\n"),
2317 // This simulates the seemingly successful write to a closed connection
2318 // if the bug is not fixed.
2319 MockWrite(
2320 "GET / HTTP/1.1\r\n"
2321 "Host: www.example.org\r\n"
2322 "Connection: keep-alive\r\n"
2323 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312324 };
2325
2326 MockRead data_reads1[] = {
2327 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2328 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2329 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2330 MockRead("Content-Length: 14\r\n\r\n"),
2331 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062332 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312333 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062334 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312335 };
2336
2337 // After calling trans->RestartWithAuth(), this is the request we should
2338 // be issuing -- the final header line contains the credentials.
2339 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232340 MockWrite(
2341 "GET / HTTP/1.1\r\n"
2342 "Host: www.example.org\r\n"
2343 "Connection: keep-alive\r\n"
2344 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312345 };
2346
2347 // Lastly, the server responds with the actual content.
2348 MockRead data_reads2[] = {
2349 MockRead("HTTP/1.1 200 OK\r\n"),
2350 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502351 MockRead("Content-Length: 5\r\n\r\n"),
2352 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312353 };
2354
[email protected]31a2bfe2010-02-09 08:03:392355 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2356 data_writes1, arraysize(data_writes1));
2357 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2358 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072359 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2360 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312361
[email protected]49639fa2011-12-20 23:22:412362 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312363
[email protected]262eec82013-03-19 21:01:362364 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502365 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412366 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312367 EXPECT_EQ(ERR_IO_PENDING, rv);
2368
2369 rv = callback1.WaitForResult();
2370 EXPECT_EQ(OK, rv);
2371
2372 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502373 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042374 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312375
[email protected]49639fa2011-12-20 23:22:412376 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312377
[email protected]49639fa2011-12-20 23:22:412378 rv = trans->RestartWithAuth(
2379 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312380 EXPECT_EQ(ERR_IO_PENDING, rv);
2381
2382 rv = callback2.WaitForResult();
2383 EXPECT_EQ(OK, rv);
2384
2385 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502386 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312387 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502388 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312389}
2390
[email protected]394816e92010-08-03 07:38:592391// Test the request-challenge-retry sequence for basic auth, over a connection
2392// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012393TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2394 HttpRequestInfo request;
2395 request.method = "GET";
bncce36dca22015-04-21 22:11:232396 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012397 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292398 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012399
2400 // Configure against proxy server "myproxy:70".
2401 session_deps_.proxy_service.reset(
2402 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512403 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012404 session_deps_.net_log = log.bound().net_log();
2405 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2406
2407 // Since we have proxy, should try to establish tunnel.
2408 MockWrite data_writes1[] = {
2409 MockWrite(
bncce36dca22015-04-21 22:11:232410 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2411 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012412 "Proxy-Connection: keep-alive\r\n\r\n"),
2413
2414 // After calling trans->RestartWithAuth(), this is the request we should
2415 // be issuing -- the final header line contains the credentials.
2416 MockWrite(
bncce36dca22015-04-21 22:11:232417 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2418 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012419 "Proxy-Connection: keep-alive\r\n"
2420 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2421
2422 MockWrite(
2423 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:232424 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012425 "Connection: keep-alive\r\n\r\n"),
2426 };
2427
2428 // The proxy responds to the connect with a 407, using a persistent
2429 // connection.
2430 MockRead data_reads1[] = {
2431 // No credentials.
2432 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2433 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
2434
2435 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2436
2437 MockRead("HTTP/1.1 200 OK\r\n"),
2438 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2439 MockRead("Content-Length: 5\r\n\r\n"),
2440 MockRead(SYNCHRONOUS, "hello"),
2441 };
2442
2443 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2444 data_writes1, arraysize(data_writes1));
2445 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2446 SSLSocketDataProvider ssl(ASYNC, OK);
2447 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2448
2449 TestCompletionCallback callback1;
2450
2451 scoped_ptr<HttpTransaction> trans(
2452 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2453
2454 int rv = trans->Start(&request, callback1.callback(), log.bound());
2455 EXPECT_EQ(ERR_IO_PENDING, rv);
2456
2457 rv = callback1.WaitForResult();
2458 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462459 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012460 log.GetEntries(&entries);
2461 size_t pos = ExpectLogContainsSomewhere(
2462 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2463 NetLog::PHASE_NONE);
2464 ExpectLogContainsSomewhere(
2465 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2466 NetLog::PHASE_NONE);
2467
2468 const HttpResponseInfo* response = trans->GetResponseInfo();
2469 ASSERT_TRUE(response != NULL);
2470 EXPECT_FALSE(response->headers->IsKeepAlive());
2471 ASSERT_FALSE(response->headers.get() == NULL);
2472 EXPECT_EQ(407, response->headers->response_code());
2473 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2474 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2475
2476 LoadTimingInfo load_timing_info;
2477 // CONNECT requests and responses are handled at the connect job level, so
2478 // the transaction does not yet have a connection.
2479 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2480
2481 TestCompletionCallback callback2;
2482
2483 rv =
2484 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2485 EXPECT_EQ(ERR_IO_PENDING, rv);
2486
2487 rv = callback2.WaitForResult();
2488 EXPECT_EQ(OK, rv);
2489
2490 response = trans->GetResponseInfo();
2491 ASSERT_TRUE(response != NULL);
2492
2493 EXPECT_TRUE(response->headers->IsKeepAlive());
2494 EXPECT_EQ(200, response->headers->response_code());
2495 EXPECT_EQ(5, response->headers->GetContentLength());
2496 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2497
2498 // The password prompt info should not be set.
2499 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2500
2501 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2502 TestLoadTimingNotReusedWithPac(load_timing_info,
2503 CONNECT_TIMING_HAS_SSL_TIMES);
2504
2505 trans.reset();
2506 session->CloseAllConnections();
2507}
2508
2509// Test the request-challenge-retry sequence for basic auth, over a connection
2510// that requires a restart when setting up an SSL tunnel.
2511TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592512 HttpRequestInfo request;
2513 request.method = "GET";
bncce36dca22015-04-21 22:11:232514 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592515 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292516 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592517
[email protected]cb9bf6ca2011-01-28 13:15:272518 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072519 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202520 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512521 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072522 session_deps_.net_log = log.bound().net_log();
2523 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272524
[email protected]394816e92010-08-03 07:38:592525 // Since we have proxy, should try to establish tunnel.
2526 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232527 MockWrite(
2528 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2529 "Host: www.example.org\r\n"
2530 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592531
bncce36dca22015-04-21 22:11:232532 // After calling trans->RestartWithAuth(), this is the request we should
2533 // be issuing -- the final header line contains the credentials.
2534 MockWrite(
2535 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2536 "Host: www.example.org\r\n"
2537 "Proxy-Connection: keep-alive\r\n"
2538 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592539
bncce36dca22015-04-21 22:11:232540 MockWrite(
2541 "GET / HTTP/1.1\r\n"
2542 "Host: www.example.org\r\n"
2543 "Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592544 };
2545
2546 // The proxy responds to the connect with a 407, using a persistent
2547 // connection.
2548 MockRead data_reads1[] = {
2549 // No credentials.
2550 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2551 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2552 MockRead("Proxy-Connection: close\r\n\r\n"),
2553
2554 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2555
2556 MockRead("HTTP/1.1 200 OK\r\n"),
2557 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502558 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062559 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592560 };
2561
2562 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2563 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072564 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062565 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072566 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592567
[email protected]49639fa2011-12-20 23:22:412568 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592569
[email protected]262eec82013-03-19 21:01:362570 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502571 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502572
[email protected]49639fa2011-12-20 23:22:412573 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592574 EXPECT_EQ(ERR_IO_PENDING, rv);
2575
2576 rv = callback1.WaitForResult();
2577 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462578 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402579 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592580 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402581 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592582 NetLog::PHASE_NONE);
2583 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402584 entries, pos,
[email protected]394816e92010-08-03 07:38:592585 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2586 NetLog::PHASE_NONE);
2587
2588 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502589 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012590 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502591 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592592 EXPECT_EQ(407, response->headers->response_code());
2593 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042594 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592595
[email protected]029c83b62013-01-24 05:28:202596 LoadTimingInfo load_timing_info;
2597 // CONNECT requests and responses are handled at the connect job level, so
2598 // the transaction does not yet have a connection.
2599 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2600
[email protected]49639fa2011-12-20 23:22:412601 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592602
[email protected]49639fa2011-12-20 23:22:412603 rv = trans->RestartWithAuth(
2604 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592605 EXPECT_EQ(ERR_IO_PENDING, rv);
2606
2607 rv = callback2.WaitForResult();
2608 EXPECT_EQ(OK, rv);
2609
2610 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502611 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592612
2613 EXPECT_TRUE(response->headers->IsKeepAlive());
2614 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502615 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592616 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2617
2618 // The password prompt info should not be set.
2619 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502620
[email protected]029c83b62013-01-24 05:28:202621 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2622 TestLoadTimingNotReusedWithPac(load_timing_info,
2623 CONNECT_TIMING_HAS_SSL_TIMES);
2624
[email protected]0b0bf032010-09-21 18:08:502625 trans.reset();
[email protected]102e27c2011-02-23 01:01:312626 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592627}
2628
[email protected]11203f012009-11-12 23:02:312629// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012630// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2631TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2632 HttpRequestInfo request;
2633 request.method = "GET";
bncce36dca22015-04-21 22:11:232634 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012635 // Ensure that proxy authentication is attempted even
2636 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292637 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012638
2639 // Configure against proxy server "myproxy:70".
2640 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512641 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012642 session_deps_.net_log = log.bound().net_log();
2643 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2644
2645 scoped_ptr<HttpTransaction> trans(
2646 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2647
2648 // Since we have proxy, should try to establish tunnel.
2649 MockWrite data_writes1[] = {
2650 MockWrite(
bncce36dca22015-04-21 22:11:232651 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2652 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012653 "Proxy-Connection: keep-alive\r\n\r\n"),
2654
2655 // After calling trans->RestartWithAuth(), this is the request we should
2656 // be issuing -- the final header line contains the credentials.
2657 MockWrite(
bncce36dca22015-04-21 22:11:232658 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2659 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012660 "Proxy-Connection: keep-alive\r\n"
2661 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2662 };
2663
2664 // The proxy responds to the connect with a 407, using a persistent
2665 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2666 MockRead data_reads1[] = {
2667 // No credentials.
2668 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2669 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2670 MockRead("Proxy-Connection: keep-alive\r\n"),
2671 MockRead("Content-Length: 10\r\n\r\n"),
2672 MockRead("0123456789"),
2673
2674 // Wrong credentials (wrong password).
2675 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2676 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2677 MockRead("Proxy-Connection: keep-alive\r\n"),
2678 MockRead("Content-Length: 10\r\n\r\n"),
2679 // No response body because the test stops reading here.
2680 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2681 };
2682
2683 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2684 data_writes1, arraysize(data_writes1));
2685 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2686
2687 TestCompletionCallback callback1;
2688
2689 int rv = trans->Start(&request, callback1.callback(), log.bound());
2690 EXPECT_EQ(ERR_IO_PENDING, rv);
2691
2692 rv = callback1.WaitForResult();
2693 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462694 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012695 log.GetEntries(&entries);
2696 size_t pos = ExpectLogContainsSomewhere(
2697 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2698 NetLog::PHASE_NONE);
2699 ExpectLogContainsSomewhere(
2700 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2701 NetLog::PHASE_NONE);
2702
2703 const HttpResponseInfo* response = trans->GetResponseInfo();
2704 ASSERT_TRUE(response);
2705 ASSERT_TRUE(response->headers);
2706 EXPECT_TRUE(response->headers->IsKeepAlive());
2707 EXPECT_EQ(407, response->headers->response_code());
2708 EXPECT_EQ(10, response->headers->GetContentLength());
2709 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2710 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2711
2712 TestCompletionCallback callback2;
2713
2714 // Wrong password (should be "bar").
2715 rv =
2716 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2717 EXPECT_EQ(ERR_IO_PENDING, rv);
2718
2719 rv = callback2.WaitForResult();
2720 EXPECT_EQ(OK, rv);
2721
2722 response = trans->GetResponseInfo();
2723 ASSERT_TRUE(response);
2724 ASSERT_TRUE(response->headers);
2725 EXPECT_TRUE(response->headers->IsKeepAlive());
2726 EXPECT_EQ(407, response->headers->response_code());
2727 EXPECT_EQ(10, response->headers->GetContentLength());
2728 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2729 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2730
2731 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2732 // out of scope.
2733 session->CloseAllConnections();
2734}
2735
2736// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2737// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2738TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272739 HttpRequestInfo request;
2740 request.method = "GET";
bncce36dca22015-04-21 22:11:232741 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272742 // Ensure that proxy authentication is attempted even
2743 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292744 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272745
[email protected]2d2697f92009-02-18 21:00:322746 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072747 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512748 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072749 session_deps_.net_log = log.bound().net_log();
2750 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322751
[email protected]262eec82013-03-19 21:01:362752 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502753 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322754
[email protected]2d2697f92009-02-18 21:00:322755 // Since we have proxy, should try to establish tunnel.
2756 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232757 MockWrite(
2758 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2759 "Host: www.example.org\r\n"
2760 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322761
bncce36dca22015-04-21 22:11:232762 // After calling trans->RestartWithAuth(), this is the request we should
2763 // be issuing -- the final header line contains the credentials.
2764 MockWrite(
2765 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2766 "Host: www.example.org\r\n"
2767 "Proxy-Connection: keep-alive\r\n"
2768 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322769 };
2770
2771 // The proxy responds to the connect with a 407, using a persistent
2772 // connection.
2773 MockRead data_reads1[] = {
2774 // No credentials.
2775 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2776 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2777 MockRead("Content-Length: 10\r\n\r\n"),
2778 MockRead("0123456789"),
2779
2780 // Wrong credentials (wrong password).
2781 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2782 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2783 MockRead("Content-Length: 10\r\n\r\n"),
2784 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062785 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322786 };
2787
[email protected]31a2bfe2010-02-09 08:03:392788 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2789 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072790 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322791
[email protected]49639fa2011-12-20 23:22:412792 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322793
[email protected]49639fa2011-12-20 23:22:412794 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422795 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322796
2797 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422798 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462799 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402800 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392801 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402802 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392803 NetLog::PHASE_NONE);
2804 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402805 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392806 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2807 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322808
[email protected]1c773ea12009-04-28 19:58:422809 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242810 ASSERT_TRUE(response);
2811 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322812 EXPECT_TRUE(response->headers->IsKeepAlive());
2813 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012814 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422815 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042816 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322817
[email protected]49639fa2011-12-20 23:22:412818 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322819
2820 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412821 rv = trans->RestartWithAuth(
2822 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422823 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322824
2825 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422826 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322827
2828 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242829 ASSERT_TRUE(response);
2830 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322831 EXPECT_TRUE(response->headers->IsKeepAlive());
2832 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012833 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422834 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042835 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132836
[email protected]e60e47a2010-07-14 03:37:182837 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2838 // out of scope.
[email protected]102e27c2011-02-23 01:01:312839 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322840}
2841
[email protected]a8e9b162009-03-12 00:06:442842// Test that we don't read the response body when we fail to establish a tunnel,
2843// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022844TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272845 HttpRequestInfo request;
2846 request.method = "GET";
bncce36dca22015-04-21 22:11:232847 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272848 request.load_flags = 0;
2849
[email protected]a8e9b162009-03-12 00:06:442850 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072851 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442852
[email protected]bb88e1d32013-05-03 23:11:072853 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442854
[email protected]262eec82013-03-19 21:01:362855 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502856 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442857
[email protected]a8e9b162009-03-12 00:06:442858 // Since we have proxy, should try to establish tunnel.
2859 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232860 MockWrite(
2861 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2862 "Host: www.example.org\r\n"
2863 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442864 };
2865
2866 // The proxy responds to the connect with a 407.
2867 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:242868 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2869 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2870 MockRead("Content-Length: 10\r\n\r\n"),
2871 MockRead("0123456789"), // Should not be reached.
2872 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:442873 };
2874
[email protected]31a2bfe2010-02-09 08:03:392875 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2876 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072877 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442878
[email protected]49639fa2011-12-20 23:22:412879 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442880
[email protected]49639fa2011-12-20 23:22:412881 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422882 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442883
2884 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422885 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442886
[email protected]1c773ea12009-04-28 19:58:422887 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242888 ASSERT_TRUE(response);
2889 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:442890 EXPECT_TRUE(response->headers->IsKeepAlive());
2891 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:422892 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442893
2894 std::string response_data;
2895 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422896 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182897
2898 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312899 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442900}
2901
ttuttle7933c112015-01-06 00:55:242902// Test that we don't pass extraneous headers from the proxy's response to the
2903// caller when the proxy responds to CONNECT with 407.
2904TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
2905 HttpRequestInfo request;
2906 request.method = "GET";
bncce36dca22015-04-21 22:11:232907 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:242908 request.load_flags = 0;
2909
2910 // Configure against proxy server "myproxy:70".
2911 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2912
2913 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2914
2915 scoped_ptr<HttpTransaction> trans(
2916 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2917
2918 // Since we have proxy, should try to establish tunnel.
2919 MockWrite data_writes[] = {
2920 MockWrite(
bncce36dca22015-04-21 22:11:232921 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2922 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:242923 "Proxy-Connection: keep-alive\r\n\r\n"),
2924 };
2925
2926 // The proxy responds to the connect with a 407.
2927 MockRead data_reads[] = {
2928 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2929 MockRead("X-Foo: bar\r\n"),
2930 MockRead("Set-Cookie: foo=bar\r\n"),
2931 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2932 MockRead("Content-Length: 10\r\n\r\n"),
2933 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2934 };
2935
2936 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
2937 arraysize(data_writes));
2938 session_deps_.socket_factory->AddSocketDataProvider(&data);
2939
2940 TestCompletionCallback callback;
2941
2942 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2943 EXPECT_EQ(ERR_IO_PENDING, rv);
2944
2945 rv = callback.WaitForResult();
2946 EXPECT_EQ(OK, rv);
2947
2948 const HttpResponseInfo* response = trans->GetResponseInfo();
2949 ASSERT_TRUE(response);
2950 ASSERT_TRUE(response->headers);
2951 EXPECT_TRUE(response->headers->IsKeepAlive());
2952 EXPECT_EQ(407, response->headers->response_code());
2953 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2954 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
2955 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
2956
2957 std::string response_data;
2958 rv = ReadTransaction(trans.get(), &response_data);
2959 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
2960
2961 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
2962 session->CloseAllConnections();
2963}
2964
[email protected]8fdbcd22010-05-05 02:54:522965// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2966// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022967TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522968 HttpRequestInfo request;
2969 request.method = "GET";
bncce36dca22015-04-21 22:11:232970 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:522971 request.load_flags = 0;
2972
[email protected]cb9bf6ca2011-01-28 13:15:272973 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072974 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272975 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412976 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272977
[email protected]8fdbcd22010-05-05 02:54:522978 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232979 MockWrite(
2980 "GET / HTTP/1.1\r\n"
2981 "Host: www.example.org\r\n"
2982 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:522983 };
2984
2985 MockRead data_reads1[] = {
2986 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2987 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2988 // Large content-length -- won't matter, as connection will be reset.
2989 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062990 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522991 };
2992
2993 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2994 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072995 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522996
[email protected]49639fa2011-12-20 23:22:412997 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522998
[email protected]49639fa2011-12-20 23:22:412999 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523000 EXPECT_EQ(ERR_IO_PENDING, rv);
3001
3002 rv = callback.WaitForResult();
3003 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3004}
3005
[email protected]7a67a8152010-11-05 18:31:103006// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3007// through a non-authenticating proxy. The request should fail with
3008// ERR_UNEXPECTED_PROXY_AUTH.
3009// Note that it is impossible to detect if an HTTP server returns a 407 through
3010// a non-authenticating proxy - there is nothing to indicate whether the
3011// response came from the proxy or the server, so it is treated as if the proxy
3012// issued the challenge.
[email protected]23e482282013-06-14 16:08:023013TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233014 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273015 HttpRequestInfo request;
3016 request.method = "GET";
bncce36dca22015-04-21 22:11:233017 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273018
[email protected]bb88e1d32013-05-03 23:11:073019 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513020 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073021 session_deps_.net_log = log.bound().net_log();
3022 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103023
[email protected]7a67a8152010-11-05 18:31:103024 // Since we have proxy, should try to establish tunnel.
3025 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233026 MockWrite(
3027 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3028 "Host: www.example.org\r\n"
3029 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103030
bncce36dca22015-04-21 22:11:233031 MockWrite(
3032 "GET / HTTP/1.1\r\n"
3033 "Host: www.example.org\r\n"
3034 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103035 };
3036
3037 MockRead data_reads1[] = {
3038 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3039
3040 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3041 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3042 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063043 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103044 };
3045
3046 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3047 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073048 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063049 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073050 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103051
[email protected]49639fa2011-12-20 23:22:413052 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103053
[email protected]262eec82013-03-19 21:01:363054 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503055 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103056
[email protected]49639fa2011-12-20 23:22:413057 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103058 EXPECT_EQ(ERR_IO_PENDING, rv);
3059
3060 rv = callback1.WaitForResult();
3061 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463062 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403063 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103064 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403065 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103066 NetLog::PHASE_NONE);
3067 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403068 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103069 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3070 NetLog::PHASE_NONE);
3071}
[email protected]2df19bb2010-08-25 20:13:463072
[email protected]029c83b62013-01-24 05:28:203073// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023074TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203075 HttpRequestInfo request1;
3076 request1.method = "GET";
bncce36dca22015-04-21 22:11:233077 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203078
3079 HttpRequestInfo request2;
3080 request2.method = "GET";
bncce36dca22015-04-21 22:11:233081 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203082
3083 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073084 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203085 ProxyService::CreateFixed("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513086 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073087 session_deps_.net_log = log.bound().net_log();
3088 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203089
3090 // Since we have proxy, should try to establish tunnel.
3091 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233092 MockWrite(
3093 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3094 "Host: www.example.org\r\n"
3095 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203096
bncce36dca22015-04-21 22:11:233097 MockWrite(
3098 "GET /1 HTTP/1.1\r\n"
3099 "Host: www.example.org\r\n"
3100 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203101
bncce36dca22015-04-21 22:11:233102 MockWrite(
3103 "GET /2 HTTP/1.1\r\n"
3104 "Host: www.example.org\r\n"
3105 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203106 };
3107
3108 // The proxy responds to the connect with a 407, using a persistent
3109 // connection.
3110 MockRead data_reads1[] = {
3111 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3112
3113 MockRead("HTTP/1.1 200 OK\r\n"),
3114 MockRead("Content-Length: 1\r\n\r\n"),
3115 MockRead(SYNCHRONOUS, "1"),
3116
3117 MockRead("HTTP/1.1 200 OK\r\n"),
3118 MockRead("Content-Length: 2\r\n\r\n"),
3119 MockRead(SYNCHRONOUS, "22"),
3120 };
3121
3122 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3123 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073124 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203125 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073126 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203127
3128 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363129 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503130 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203131
3132 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3133 EXPECT_EQ(ERR_IO_PENDING, rv);
3134
3135 rv = callback1.WaitForResult();
3136 EXPECT_EQ(OK, rv);
3137
3138 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3139 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503140 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203141 EXPECT_EQ(1, response1->headers->GetContentLength());
3142
3143 LoadTimingInfo load_timing_info1;
3144 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3145 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3146
3147 trans1.reset();
3148
3149 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363150 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503151 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203152
3153 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3154 EXPECT_EQ(ERR_IO_PENDING, rv);
3155
3156 rv = callback2.WaitForResult();
3157 EXPECT_EQ(OK, rv);
3158
3159 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3160 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503161 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203162 EXPECT_EQ(2, response2->headers->GetContentLength());
3163
3164 LoadTimingInfo load_timing_info2;
3165 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3166 TestLoadTimingReused(load_timing_info2);
3167
3168 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3169
3170 trans2.reset();
3171 session->CloseAllConnections();
3172}
3173
3174// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023175TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203176 HttpRequestInfo request1;
3177 request1.method = "GET";
bncce36dca22015-04-21 22:11:233178 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203179
3180 HttpRequestInfo request2;
3181 request2.method = "GET";
bncce36dca22015-04-21 22:11:233182 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203183
3184 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073185 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203186 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513187 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073188 session_deps_.net_log = log.bound().net_log();
3189 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203190
3191 // Since we have proxy, should try to establish tunnel.
3192 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233193 MockWrite(
3194 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3195 "Host: www.example.org\r\n"
3196 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203197
bncce36dca22015-04-21 22:11:233198 MockWrite(
3199 "GET /1 HTTP/1.1\r\n"
3200 "Host: www.example.org\r\n"
3201 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203202
bncce36dca22015-04-21 22:11:233203 MockWrite(
3204 "GET /2 HTTP/1.1\r\n"
3205 "Host: www.example.org\r\n"
3206 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203207 };
3208
3209 // The proxy responds to the connect with a 407, using a persistent
3210 // connection.
3211 MockRead data_reads1[] = {
3212 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3213
3214 MockRead("HTTP/1.1 200 OK\r\n"),
3215 MockRead("Content-Length: 1\r\n\r\n"),
3216 MockRead(SYNCHRONOUS, "1"),
3217
3218 MockRead("HTTP/1.1 200 OK\r\n"),
3219 MockRead("Content-Length: 2\r\n\r\n"),
3220 MockRead(SYNCHRONOUS, "22"),
3221 };
3222
3223 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3224 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073225 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203226 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203228
3229 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363230 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503231 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203232
3233 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3234 EXPECT_EQ(ERR_IO_PENDING, rv);
3235
3236 rv = callback1.WaitForResult();
3237 EXPECT_EQ(OK, rv);
3238
3239 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3240 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503241 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203242 EXPECT_EQ(1, response1->headers->GetContentLength());
3243
3244 LoadTimingInfo load_timing_info1;
3245 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3246 TestLoadTimingNotReusedWithPac(load_timing_info1,
3247 CONNECT_TIMING_HAS_SSL_TIMES);
3248
3249 trans1.reset();
3250
3251 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363252 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503253 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203254
3255 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3256 EXPECT_EQ(ERR_IO_PENDING, rv);
3257
3258 rv = callback2.WaitForResult();
3259 EXPECT_EQ(OK, rv);
3260
3261 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3262 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503263 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203264 EXPECT_EQ(2, response2->headers->GetContentLength());
3265
3266 LoadTimingInfo load_timing_info2;
3267 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3268 TestLoadTimingReusedWithPac(load_timing_info2);
3269
3270 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3271
3272 trans2.reset();
3273 session->CloseAllConnections();
3274}
3275
[email protected]2df19bb2010-08-25 20:13:463276// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023277TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273278 HttpRequestInfo request;
3279 request.method = "GET";
bncce36dca22015-04-21 22:11:233280 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273281
[email protected]2df19bb2010-08-25 20:13:463282 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073283 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113284 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513285 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073286 session_deps_.net_log = log.bound().net_log();
3287 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463288
[email protected]2df19bb2010-08-25 20:13:463289 // Since we have proxy, should use full url
3290 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233291 MockWrite(
3292 "GET http://www.example.org/ HTTP/1.1\r\n"
3293 "Host: www.example.org\r\n"
3294 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463295 };
3296
3297 MockRead data_reads1[] = {
3298 MockRead("HTTP/1.1 200 OK\r\n"),
3299 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3300 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063301 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463302 };
3303
3304 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3305 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073306 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063307 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073308 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463309
[email protected]49639fa2011-12-20 23:22:413310 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463311
[email protected]262eec82013-03-19 21:01:363312 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503313 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503314
[email protected]49639fa2011-12-20 23:22:413315 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463316 EXPECT_EQ(ERR_IO_PENDING, rv);
3317
3318 rv = callback1.WaitForResult();
3319 EXPECT_EQ(OK, rv);
3320
[email protected]58e32bb2013-01-21 18:23:253321 LoadTimingInfo load_timing_info;
3322 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3323 TestLoadTimingNotReused(load_timing_info,
3324 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3325
[email protected]2df19bb2010-08-25 20:13:463326 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503327 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463328
3329 EXPECT_TRUE(response->headers->IsKeepAlive());
3330 EXPECT_EQ(200, response->headers->response_code());
3331 EXPECT_EQ(100, response->headers->GetContentLength());
3332 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3333
3334 // The password prompt info should not be set.
3335 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3336}
3337
[email protected]7642b5ae2010-09-01 20:55:173338// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023339TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273340 HttpRequestInfo request;
3341 request.method = "GET";
bncce36dca22015-04-21 22:11:233342 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273343 request.load_flags = 0;
3344
[email protected]7642b5ae2010-09-01 20:55:173345 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073346 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113347 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513348 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073349 session_deps_.net_log = log.bound().net_log();
3350 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173351
bncce36dca22015-04-21 22:11:233352 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463353 scoped_ptr<SpdyFrame> req(
3354 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133355 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:173356
[email protected]23e482282013-06-14 16:08:023357 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3358 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173359 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133360 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:173361 };
3362
rch8e6c6c42015-05-01 14:05:133363 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3364 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073365 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173366
[email protected]8ddf8322012-02-23 18:08:063367 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023368 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073369 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173370
[email protected]49639fa2011-12-20 23:22:413371 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173372
[email protected]262eec82013-03-19 21:01:363373 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503374 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503375
[email protected]49639fa2011-12-20 23:22:413376 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173377 EXPECT_EQ(ERR_IO_PENDING, rv);
3378
3379 rv = callback1.WaitForResult();
3380 EXPECT_EQ(OK, rv);
3381
[email protected]58e32bb2013-01-21 18:23:253382 LoadTimingInfo load_timing_info;
3383 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3384 TestLoadTimingNotReused(load_timing_info,
3385 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3386
[email protected]7642b5ae2010-09-01 20:55:173387 const HttpResponseInfo* response = trans->GetResponseInfo();
3388 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503389 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173390 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3391
3392 std::string response_data;
3393 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233394 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173395}
3396
[email protected]1c173852014-06-19 12:51:503397// Verifies that a session which races and wins against the owning transaction
3398// (completing prior to host resolution), doesn't fail the transaction.
3399// Regression test for crbug.com/334413.
3400TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3401 HttpRequestInfo request;
3402 request.method = "GET";
bncce36dca22015-04-21 22:11:233403 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:503404 request.load_flags = 0;
3405
3406 // Configure SPDY proxy server "proxy:70".
3407 session_deps_.proxy_service.reset(
3408 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513409 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:503410 session_deps_.net_log = log.bound().net_log();
3411 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3412
bncce36dca22015-04-21 22:11:233413 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:503414 scoped_ptr<SpdyFrame> req(
3415 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133416 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:503417
3418 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3419 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3420 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133421 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:503422 };
3423
rch8e6c6c42015-05-01 14:05:133424 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3425 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:503426 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3427
3428 SSLSocketDataProvider ssl(ASYNC, OK);
3429 ssl.SetNextProto(GetParam());
3430 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3431
3432 TestCompletionCallback callback1;
3433
3434 scoped_ptr<HttpTransaction> trans(
3435 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3436
3437 // Stall the hostname resolution begun by the transaction.
3438 session_deps_.host_resolver->set_synchronous_mode(false);
3439 session_deps_.host_resolver->set_ondemand_mode(true);
3440
3441 int rv = trans->Start(&request, callback1.callback(), log.bound());
3442 EXPECT_EQ(ERR_IO_PENDING, rv);
3443
3444 // Race a session to the proxy, which completes first.
3445 session_deps_.host_resolver->set_ondemand_mode(false);
3446 SpdySessionKey key(
3447 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3448 base::WeakPtr<SpdySession> spdy_session =
3449 CreateSecureSpdySession(session, key, log.bound());
3450
3451 // Unstall the resolution begun by the transaction.
3452 session_deps_.host_resolver->set_ondemand_mode(true);
3453 session_deps_.host_resolver->ResolveAllPending();
3454
3455 EXPECT_FALSE(callback1.have_result());
3456 rv = callback1.WaitForResult();
3457 EXPECT_EQ(OK, rv);
3458
3459 const HttpResponseInfo* response = trans->GetResponseInfo();
3460 ASSERT_TRUE(response != NULL);
3461 ASSERT_TRUE(response->headers.get() != NULL);
3462 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3463
3464 std::string response_data;
3465 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3466 EXPECT_EQ(kUploadData, response_data);
3467}
3468
[email protected]dc7bd1c52010-11-12 00:01:133469// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023470TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273471 HttpRequestInfo request;
3472 request.method = "GET";
bncce36dca22015-04-21 22:11:233473 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273474 request.load_flags = 0;
3475
[email protected]79cb5c12011-09-12 13:12:043476 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073477 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043478 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513479 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073480 session_deps_.net_log = log.bound().net_log();
3481 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133482
[email protected]dc7bd1c52010-11-12 00:01:133483 // The first request will be a bare GET, the second request will be a
3484 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193485 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463486 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133487 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463488 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133489 };
[email protected]ff98d7f02012-03-22 21:44:193490 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463491 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3492 arraysize(kExtraAuthorizationHeaders) / 2,
3493 false,
3494 3,
3495 LOWEST,
3496 false));
[email protected]dc7bd1c52010-11-12 00:01:133497 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133498 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:133499 };
3500
3501 // The first response is a 407 proxy authentication challenge, and the second
3502 // response will be a 200 response since the second request includes a valid
3503 // Authorization header.
3504 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463505 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133506 };
[email protected]ff98d7f02012-03-22 21:44:193507 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023508 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133509 "407 Proxy Authentication Required",
3510 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3511 1));
[email protected]ff98d7f02012-03-22 21:44:193512 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023513 spdy_util_.ConstructSpdyBodyFrame(1, true));
3514 scoped_ptr<SpdyFrame> resp_data(
3515 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3516 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133517 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133518 CreateMockRead(*resp_authentication, 1),
3519 CreateMockRead(*body_authentication, 2),
3520 CreateMockRead(*resp_data, 4),
3521 CreateMockRead(*body_data, 5),
3522 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:133523 };
3524
rch8e6c6c42015-05-01 14:05:133525 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3526 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073527 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133528
[email protected]8ddf8322012-02-23 18:08:063529 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023530 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073531 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133532
[email protected]49639fa2011-12-20 23:22:413533 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133534
[email protected]262eec82013-03-19 21:01:363535 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503536 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133537
[email protected]49639fa2011-12-20 23:22:413538 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133539 EXPECT_EQ(ERR_IO_PENDING, rv);
3540
3541 rv = callback1.WaitForResult();
3542 EXPECT_EQ(OK, rv);
3543
3544 const HttpResponseInfo* const response = trans->GetResponseInfo();
3545
3546 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503547 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133548 EXPECT_EQ(407, response->headers->response_code());
3549 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043550 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133551
[email protected]49639fa2011-12-20 23:22:413552 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133553
[email protected]49639fa2011-12-20 23:22:413554 rv = trans->RestartWithAuth(
3555 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133556 EXPECT_EQ(ERR_IO_PENDING, rv);
3557
3558 rv = callback2.WaitForResult();
3559 EXPECT_EQ(OK, rv);
3560
3561 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3562
3563 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503564 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133565 EXPECT_EQ(200, response_restart->headers->response_code());
3566 // The password prompt info should not be set.
3567 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3568}
3569
[email protected]d9da5fe2010-10-13 22:37:163570// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023571TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273572 HttpRequestInfo request;
3573 request.method = "GET";
bncce36dca22015-04-21 22:11:233574 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273575 request.load_flags = 0;
3576
[email protected]d9da5fe2010-10-13 22:37:163577 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073578 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113579 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513580 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073581 session_deps_.net_log = log.bound().net_log();
3582 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163583
[email protected]262eec82013-03-19 21:01:363584 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503585 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163586
bncce36dca22015-04-21 22:11:233587 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343588 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233589 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3590 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:163591
bncce36dca22015-04-21 22:11:233592 const char get[] =
3593 "GET / HTTP/1.1\r\n"
3594 "Host: www.example.org\r\n"
3595 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193596 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023597 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3598 scoped_ptr<SpdyFrame> conn_resp(
3599 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163600 const char resp[] = "HTTP/1.1 200 OK\r\n"
3601 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193602 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023603 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193604 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023605 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193606 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203607 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043608
3609 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133610 CreateMockWrite(*connect, 0),
3611 CreateMockWrite(*wrapped_get, 2),
3612 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:043613 };
3614
[email protected]d9da5fe2010-10-13 22:37:163615 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133616 CreateMockRead(*conn_resp, 1, ASYNC),
3617 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
3618 CreateMockRead(*wrapped_body, 4, ASYNC),
3619 CreateMockRead(*wrapped_body, 5, ASYNC),
3620 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:163621 };
3622
rch8e6c6c42015-05-01 14:05:133623 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3624 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073625 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163626
[email protected]8ddf8322012-02-23 18:08:063627 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023628 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073629 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063630 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073631 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163632
[email protected]49639fa2011-12-20 23:22:413633 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163634
[email protected]49639fa2011-12-20 23:22:413635 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163636 EXPECT_EQ(ERR_IO_PENDING, rv);
3637
3638 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:133639 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:163640
[email protected]58e32bb2013-01-21 18:23:253641 LoadTimingInfo load_timing_info;
3642 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3643 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3644
[email protected]d9da5fe2010-10-13 22:37:163645 const HttpResponseInfo* response = trans->GetResponseInfo();
3646 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503647 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163648 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3649
3650 std::string response_data;
3651 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3652 EXPECT_EQ("1234567890", response_data);
3653}
3654
3655// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023656TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273657 HttpRequestInfo request;
3658 request.method = "GET";
bncce36dca22015-04-21 22:11:233659 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273660 request.load_flags = 0;
3661
[email protected]d9da5fe2010-10-13 22:37:163662 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073663 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113664 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513665 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073666 session_deps_.net_log = log.bound().net_log();
3667 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163668
[email protected]262eec82013-03-19 21:01:363669 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503670 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163671
bncce36dca22015-04-21 22:11:233672 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343673 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233674 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3675 // fetch https://www.example.org/ via SPDY
3676 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:463677 scoped_ptr<SpdyFrame> get(
3678 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023679 scoped_ptr<SpdyFrame> wrapped_get(
3680 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3681 scoped_ptr<SpdyFrame> conn_resp(
3682 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3683 scoped_ptr<SpdyFrame> get_resp(
3684 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193685 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023686 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3687 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3688 scoped_ptr<SpdyFrame> wrapped_body(
3689 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193690 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203691 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193692 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203693 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043694
3695 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:093696 CreateMockWrite(*connect, 0),
3697 CreateMockWrite(*wrapped_get, 2),
3698 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:043699 CreateMockWrite(*window_update_body, 7),
3700 };
3701
[email protected]d9da5fe2010-10-13 22:37:163702 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:093703 CreateMockRead(*conn_resp, 1, ASYNC),
3704 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:133705 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:093706 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:133707 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163708 };
3709
rch32320842015-05-16 15:57:093710 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3711 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073712 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163713
[email protected]8ddf8322012-02-23 18:08:063714 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023715 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073716 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063717 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023718 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073719 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163720
[email protected]49639fa2011-12-20 23:22:413721 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163722
[email protected]49639fa2011-12-20 23:22:413723 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163724 EXPECT_EQ(ERR_IO_PENDING, rv);
3725
rch32320842015-05-16 15:57:093726 // Allow the SpdyProxyClientSocket's write callback to complete.
3727 base::MessageLoop::current()->RunUntilIdle();
3728 // Now allow the read of the response to complete.
3729 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:163730 rv = callback1.WaitForResult();
3731 EXPECT_EQ(OK, rv);
3732
[email protected]58e32bb2013-01-21 18:23:253733 LoadTimingInfo load_timing_info;
3734 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3735 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3736
[email protected]d9da5fe2010-10-13 22:37:163737 const HttpResponseInfo* response = trans->GetResponseInfo();
3738 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503739 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163740 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3741
3742 std::string response_data;
3743 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233744 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163745}
3746
3747// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023748TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273749 HttpRequestInfo request;
3750 request.method = "GET";
bncce36dca22015-04-21 22:11:233751 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273752 request.load_flags = 0;
3753
[email protected]d9da5fe2010-10-13 22:37:163754 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073755 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113756 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513757 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073758 session_deps_.net_log = log.bound().net_log();
3759 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163760
[email protected]262eec82013-03-19 21:01:363761 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503762 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163763
bncce36dca22015-04-21 22:11:233764 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343765 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233766 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:203767 scoped_ptr<SpdyFrame> get(
3768 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163769
3770 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133771 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:163772 };
3773
[email protected]23e482282013-06-14 16:08:023774 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3775 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163776 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133777 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:163778 };
3779
rch8e6c6c42015-05-01 14:05:133780 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3781 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073782 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163783
[email protected]8ddf8322012-02-23 18:08:063784 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023785 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073786 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063787 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023788 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073789 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163790
[email protected]49639fa2011-12-20 23:22:413791 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163792
[email protected]49639fa2011-12-20 23:22:413793 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163794 EXPECT_EQ(ERR_IO_PENDING, rv);
3795
3796 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173797 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163798
[email protected]4eddbc732012-08-09 05:40:173799 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163800}
3801
[email protected]f6c63db52013-02-02 00:35:223802// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3803// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023804TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223805 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3806 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073807 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223808 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513809 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073810 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223811 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:503812 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223813
3814 HttpRequestInfo request1;
3815 request1.method = "GET";
bncce36dca22015-04-21 22:11:233816 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223817 request1.load_flags = 0;
3818
3819 HttpRequestInfo request2;
3820 request2.method = "GET";
bncce36dca22015-04-21 22:11:233821 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:223822 request2.load_flags = 0;
3823
bncce36dca22015-04-21 22:11:233824 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343825 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233826 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023827 scoped_ptr<SpdyFrame> conn_resp1(
3828 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223829
bncce36dca22015-04-21 22:11:233830 // Fetch https://www.example.org/ via HTTP.
3831 const char get1[] =
3832 "GET / HTTP/1.1\r\n"
3833 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223834 "Connection: keep-alive\r\n\r\n";
3835 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023836 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223837 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3838 "Content-Length: 1\r\n\r\n";
3839 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023840 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3841 scoped_ptr<SpdyFrame> wrapped_body1(
3842 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223843 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203844 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223845
bncce36dca22015-04-21 22:11:233846 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293847 SpdyHeaderBlock connect2_block;
3848 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnc6b996d532015-07-29 10:51:323849 if (GetParam() >= kProtoHTTP2MinimumVersion) {
3850 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
3851 } else {
3852 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
3853 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
3854 }
[email protected]745aa9c2014-06-27 02:21:293855 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223856 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293857 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393858
[email protected]23e482282013-06-14 16:08:023859 scoped_ptr<SpdyFrame> conn_resp2(
3860 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223861
bncce36dca22015-04-21 22:11:233862 // Fetch https://mail.example.org/ via HTTP.
3863 const char get2[] =
3864 "GET / HTTP/1.1\r\n"
3865 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223866 "Connection: keep-alive\r\n\r\n";
3867 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023868 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223869 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3870 "Content-Length: 2\r\n\r\n";
3871 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023872 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223873 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023874 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223875
3876 MockWrite spdy_writes[] = {
3877 CreateMockWrite(*connect1, 0),
3878 CreateMockWrite(*wrapped_get1, 2),
3879 CreateMockWrite(*connect2, 5),
3880 CreateMockWrite(*wrapped_get2, 7),
3881 };
3882
3883 MockRead spdy_reads[] = {
3884 CreateMockRead(*conn_resp1, 1, ASYNC),
3885 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3886 CreateMockRead(*wrapped_body1, 4, ASYNC),
3887 CreateMockRead(*conn_resp2, 6, ASYNC),
3888 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3889 CreateMockRead(*wrapped_body2, 9, ASYNC),
3890 MockRead(ASYNC, 0, 10),
3891 };
3892
mmenke11eb5152015-06-09 14:50:503893 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3894 arraysize(spdy_writes));
3895 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223896
3897 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023898 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:503899 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223900 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:503901 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223902 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:503903 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223904
3905 TestCompletionCallback callback;
3906
[email protected]262eec82013-03-19 21:01:363907 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503908 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223909 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:503910 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223911
3912 LoadTimingInfo load_timing_info;
3913 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3914 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3915
3916 const HttpResponseInfo* response = trans->GetResponseInfo();
3917 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503918 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223919 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3920
3921 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:293922 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:503923 rv = trans->Read(buf.get(), 256, callback.callback());
3924 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223925
[email protected]262eec82013-03-19 21:01:363926 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503927 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223928 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:503929 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223930
3931 LoadTimingInfo load_timing_info2;
3932 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3933 // Even though the SPDY connection is reused, a new tunnelled connection has
3934 // to be created, so the socket's load timing looks like a fresh connection.
3935 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3936
3937 // The requests should have different IDs, since they each are using their own
3938 // separate stream.
3939 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3940
mmenke11eb5152015-06-09 14:50:503941 rv = trans2->Read(buf.get(), 256, callback.callback());
3942 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223943}
3944
3945// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3946// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023947TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223948 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3949 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073950 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223951 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513952 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073953 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223954 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:503955 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223956
3957 HttpRequestInfo request1;
3958 request1.method = "GET";
bncce36dca22015-04-21 22:11:233959 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223960 request1.load_flags = 0;
3961
3962 HttpRequestInfo request2;
3963 request2.method = "GET";
bncce36dca22015-04-21 22:11:233964 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:223965 request2.load_flags = 0;
3966
bncce36dca22015-04-21 22:11:233967 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343968 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233969 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023970 scoped_ptr<SpdyFrame> conn_resp1(
3971 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223972
bncce36dca22015-04-21 22:11:233973 // Fetch https://www.example.org/ via HTTP.
3974 const char get1[] =
3975 "GET / HTTP/1.1\r\n"
3976 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223977 "Connection: keep-alive\r\n\r\n";
3978 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023979 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223980 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3981 "Content-Length: 1\r\n\r\n";
3982 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023983 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3984 scoped_ptr<SpdyFrame> wrapped_body1(
3985 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223986 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203987 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223988
bncce36dca22015-04-21 22:11:233989 // Fetch https://www.example.org/2 via HTTP.
3990 const char get2[] =
3991 "GET /2 HTTP/1.1\r\n"
3992 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223993 "Connection: keep-alive\r\n\r\n";
3994 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023995 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223996 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3997 "Content-Length: 2\r\n\r\n";
3998 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023999 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224000 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024001 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224002
4003 MockWrite spdy_writes[] = {
4004 CreateMockWrite(*connect1, 0),
4005 CreateMockWrite(*wrapped_get1, 2),
4006 CreateMockWrite(*wrapped_get2, 5),
4007 };
4008
4009 MockRead spdy_reads[] = {
4010 CreateMockRead(*conn_resp1, 1, ASYNC),
4011 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4012 CreateMockRead(*wrapped_body1, 4, ASYNC),
4013 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4014 CreateMockRead(*wrapped_body2, 7, ASYNC),
4015 MockRead(ASYNC, 0, 8),
4016 };
4017
mmenke11eb5152015-06-09 14:50:504018 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4019 arraysize(spdy_writes));
4020 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224021
4022 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024023 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504024 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224025 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504026 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224027
4028 TestCompletionCallback callback;
4029
[email protected]262eec82013-03-19 21:01:364030 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504031 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224032 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4033 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224034
4035 rv = callback.WaitForResult();
4036 EXPECT_EQ(OK, rv);
4037
4038 LoadTimingInfo load_timing_info;
4039 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4040 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4041
4042 const HttpResponseInfo* response = trans->GetResponseInfo();
4043 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504044 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224045 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4046
4047 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294048 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504049 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224050 trans.reset();
4051
[email protected]262eec82013-03-19 21:01:364052 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504053 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224054 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4055 EXPECT_EQ(ERR_IO_PENDING, rv);
4056
[email protected]f6c63db52013-02-02 00:35:224057 rv = callback.WaitForResult();
4058 EXPECT_EQ(OK, rv);
4059
4060 LoadTimingInfo load_timing_info2;
4061 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4062 TestLoadTimingReused(load_timing_info2);
4063
4064 // The requests should have the same ID.
4065 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4066
[email protected]90499482013-06-01 00:39:504067 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224068}
4069
4070// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4071// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504072TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224073 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074074 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224075 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514076 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074077 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224078 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504079 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224080
4081 HttpRequestInfo request1;
4082 request1.method = "GET";
bncce36dca22015-04-21 22:11:234083 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224084 request1.load_flags = 0;
4085
4086 HttpRequestInfo request2;
4087 request2.method = "GET";
bncce36dca22015-04-21 22:11:234088 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224089 request2.load_flags = 0;
4090
bncce36dca22015-04-21 22:11:234091 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024092 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234093 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294094 scoped_ptr<SpdyFrame> get1(
4095 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024096 scoped_ptr<SpdyFrame> get_resp1(
4097 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4098 scoped_ptr<SpdyFrame> body1(
4099 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224100
bncce36dca22015-04-21 22:11:234101 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024102 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234103 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294104 scoped_ptr<SpdyFrame> get2(
4105 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024106 scoped_ptr<SpdyFrame> get_resp2(
4107 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4108 scoped_ptr<SpdyFrame> body2(
4109 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224110
4111 MockWrite spdy_writes[] = {
4112 CreateMockWrite(*get1, 0),
4113 CreateMockWrite(*get2, 3),
4114 };
4115
4116 MockRead spdy_reads[] = {
4117 CreateMockRead(*get_resp1, 1, ASYNC),
4118 CreateMockRead(*body1, 2, ASYNC),
4119 CreateMockRead(*get_resp2, 4, ASYNC),
4120 CreateMockRead(*body2, 5, ASYNC),
4121 MockRead(ASYNC, 0, 6),
4122 };
4123
mmenke11eb5152015-06-09 14:50:504124 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4125 arraysize(spdy_writes));
4126 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224127
4128 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024129 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504130 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224131
4132 TestCompletionCallback callback;
4133
[email protected]262eec82013-03-19 21:01:364134 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504135 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224136 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504137 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224138
4139 LoadTimingInfo load_timing_info;
4140 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4141 TestLoadTimingNotReused(load_timing_info,
4142 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4143
4144 const HttpResponseInfo* response = trans->GetResponseInfo();
4145 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504146 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224147 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4148
4149 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294150 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504151 rv = trans->Read(buf.get(), 256, callback.callback());
4152 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224153 // Delete the first request, so the second one can reuse the socket.
4154 trans.reset();
4155
[email protected]262eec82013-03-19 21:01:364156 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504157 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224158 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504159 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224160
4161 LoadTimingInfo load_timing_info2;
4162 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4163 TestLoadTimingReused(load_timing_info2);
4164
4165 // The requests should have the same ID.
4166 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4167
mmenke11eb5152015-06-09 14:50:504168 rv = trans2->Read(buf.get(), 256, callback.callback());
4169 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224170}
4171
[email protected]2df19bb2010-08-25 20:13:464172// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024173TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464174 HttpRequestInfo request;
4175 request.method = "GET";
bncce36dca22015-04-21 22:11:234176 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464177 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294178 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464179
[email protected]79cb5c12011-09-12 13:12:044180 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074181 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:044182 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:514183 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074184 session_deps_.net_log = log.bound().net_log();
4185 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274186
[email protected]2df19bb2010-08-25 20:13:464187 // Since we have proxy, should use full url
4188 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234189 MockWrite(
4190 "GET http://www.example.org/ HTTP/1.1\r\n"
4191 "Host: www.example.org\r\n"
4192 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464193
bncce36dca22015-04-21 22:11:234194 // After calling trans->RestartWithAuth(), this is the request we should
4195 // be issuing -- the final header line contains the credentials.
4196 MockWrite(
4197 "GET http://www.example.org/ HTTP/1.1\r\n"
4198 "Host: www.example.org\r\n"
4199 "Proxy-Connection: keep-alive\r\n"
4200 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464201 };
4202
4203 // The proxy responds to the GET with a 407, using a persistent
4204 // connection.
4205 MockRead data_reads1[] = {
4206 // No credentials.
4207 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4208 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4209 MockRead("Proxy-Connection: keep-alive\r\n"),
4210 MockRead("Content-Length: 0\r\n\r\n"),
4211
4212 MockRead("HTTP/1.1 200 OK\r\n"),
4213 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4214 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064215 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464216 };
4217
4218 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4219 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074220 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064221 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074222 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464223
[email protected]49639fa2011-12-20 23:22:414224 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464225
[email protected]262eec82013-03-19 21:01:364226 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504227 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504228
[email protected]49639fa2011-12-20 23:22:414229 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464230 EXPECT_EQ(ERR_IO_PENDING, rv);
4231
4232 rv = callback1.WaitForResult();
4233 EXPECT_EQ(OK, rv);
4234
[email protected]58e32bb2013-01-21 18:23:254235 LoadTimingInfo load_timing_info;
4236 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4237 TestLoadTimingNotReused(load_timing_info,
4238 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4239
[email protected]2df19bb2010-08-25 20:13:464240 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504241 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504242 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464243 EXPECT_EQ(407, response->headers->response_code());
4244 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044245 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464246
[email protected]49639fa2011-12-20 23:22:414247 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464248
[email protected]49639fa2011-12-20 23:22:414249 rv = trans->RestartWithAuth(
4250 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464251 EXPECT_EQ(ERR_IO_PENDING, rv);
4252
4253 rv = callback2.WaitForResult();
4254 EXPECT_EQ(OK, rv);
4255
[email protected]58e32bb2013-01-21 18:23:254256 load_timing_info = LoadTimingInfo();
4257 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4258 // Retrying with HTTP AUTH is considered to be reusing a socket.
4259 TestLoadTimingReused(load_timing_info);
4260
[email protected]2df19bb2010-08-25 20:13:464261 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504262 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464263
4264 EXPECT_TRUE(response->headers->IsKeepAlive());
4265 EXPECT_EQ(200, response->headers->response_code());
4266 EXPECT_EQ(100, response->headers->GetContentLength());
4267 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4268
4269 // The password prompt info should not be set.
4270 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4271}
4272
[email protected]23e482282013-06-14 16:08:024273void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084274 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424275 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084276 request.method = "GET";
bncce36dca22015-04-21 22:11:234277 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084278 request.load_flags = 0;
4279
[email protected]cb9bf6ca2011-01-28 13:15:274280 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074281 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:074282 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274283
[email protected]c744cf22009-02-27 07:28:084284 // Since we have proxy, should try to establish tunnel.
4285 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234286 MockWrite(
4287 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4288 "Host: www.example.org\r\n"
4289 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084290 };
4291
4292 MockRead data_reads[] = {
4293 status,
4294 MockRead("Content-Length: 10\r\n\r\n"),
4295 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064296 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084297 };
4298
[email protected]31a2bfe2010-02-09 08:03:394299 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4300 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074301 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084302
[email protected]49639fa2011-12-20 23:22:414303 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084304
[email protected]262eec82013-03-19 21:01:364305 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504306 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504307
[email protected]49639fa2011-12-20 23:22:414308 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424309 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084310
4311 rv = callback.WaitForResult();
4312 EXPECT_EQ(expected_status, rv);
4313}
4314
[email protected]23e482282013-06-14 16:08:024315void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234316 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084317 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424318 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084319}
4320
[email protected]23e482282013-06-14 16:08:024321TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084322 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4323}
4324
[email protected]23e482282013-06-14 16:08:024325TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084326 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4327}
4328
[email protected]23e482282013-06-14 16:08:024329TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084330 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4331}
4332
[email protected]23e482282013-06-14 16:08:024333TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084334 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4335}
4336
[email protected]23e482282013-06-14 16:08:024337TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084338 ConnectStatusHelper(
4339 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4340}
4341
[email protected]23e482282013-06-14 16:08:024342TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084343 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4344}
4345
[email protected]23e482282013-06-14 16:08:024346TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084347 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4348}
4349
[email protected]23e482282013-06-14 16:08:024350TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084351 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4352}
4353
[email protected]23e482282013-06-14 16:08:024354TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084355 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4356}
4357
[email protected]23e482282013-06-14 16:08:024358TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084359 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4360}
4361
[email protected]23e482282013-06-14 16:08:024362TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084363 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4364}
4365
[email protected]23e482282013-06-14 16:08:024366TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084367 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4368}
4369
[email protected]23e482282013-06-14 16:08:024370TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084371 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4372}
4373
[email protected]23e482282013-06-14 16:08:024374TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084375 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4376}
4377
[email protected]23e482282013-06-14 16:08:024378TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084379 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4380}
4381
[email protected]23e482282013-06-14 16:08:024382TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084383 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4384}
4385
[email protected]0a17aab32014-04-24 03:32:374386TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4387 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4388}
4389
[email protected]23e482282013-06-14 16:08:024390TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084391 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4392}
4393
[email protected]23e482282013-06-14 16:08:024394TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084395 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4396}
4397
[email protected]23e482282013-06-14 16:08:024398TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084399 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4400}
4401
[email protected]23e482282013-06-14 16:08:024402TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084403 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4404}
4405
[email protected]23e482282013-06-14 16:08:024406TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084407 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4408}
4409
[email protected]23e482282013-06-14 16:08:024410TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084411 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4412}
4413
[email protected]23e482282013-06-14 16:08:024414TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084415 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4416}
4417
[email protected]23e482282013-06-14 16:08:024418TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084419 ConnectStatusHelperWithExpectedStatus(
4420 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544421 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084422}
4423
[email protected]23e482282013-06-14 16:08:024424TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084425 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4426}
4427
[email protected]23e482282013-06-14 16:08:024428TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084429 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4430}
4431
[email protected]23e482282013-06-14 16:08:024432TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084433 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4434}
4435
[email protected]23e482282013-06-14 16:08:024436TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084437 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4438}
4439
[email protected]23e482282013-06-14 16:08:024440TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084441 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4442}
4443
[email protected]23e482282013-06-14 16:08:024444TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084445 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4446}
4447
[email protected]23e482282013-06-14 16:08:024448TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084449 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4450}
4451
[email protected]23e482282013-06-14 16:08:024452TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084453 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4454}
4455
[email protected]23e482282013-06-14 16:08:024456TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084457 ConnectStatusHelper(
4458 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4459}
4460
[email protected]23e482282013-06-14 16:08:024461TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084462 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4463}
4464
[email protected]23e482282013-06-14 16:08:024465TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084466 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4467}
4468
[email protected]23e482282013-06-14 16:08:024469TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084470 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4471}
4472
[email protected]23e482282013-06-14 16:08:024473TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084474 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4475}
4476
[email protected]23e482282013-06-14 16:08:024477TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084478 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4479}
4480
[email protected]23e482282013-06-14 16:08:024481TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084482 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4483}
4484
[email protected]23e482282013-06-14 16:08:024485TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084486 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4487}
4488
[email protected]038e9a32008-10-08 22:40:164489// Test the flow when both the proxy server AND origin server require
4490// authentication. Again, this uses basic auth for both since that is
4491// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024492TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274493 HttpRequestInfo request;
4494 request.method = "GET";
bncce36dca22015-04-21 22:11:234495 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274496 request.load_flags = 0;
4497
[email protected]038e9a32008-10-08 22:40:164498 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074499 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4500 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4501
4502 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414503 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164504
[email protected]f9ee6b52008-11-08 06:46:234505 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234506 MockWrite(
4507 "GET http://www.example.org/ HTTP/1.1\r\n"
4508 "Host: www.example.org\r\n"
4509 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:234510 };
4511
[email protected]038e9a32008-10-08 22:40:164512 MockRead data_reads1[] = {
4513 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4514 // Give a couple authenticate options (only the middle one is actually
4515 // supported).
[email protected]22927ad2009-09-21 19:56:194516 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164517 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4518 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4519 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4520 // Large content-length -- won't matter, as connection will be reset.
4521 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064522 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164523 };
4524
4525 // After calling trans->RestartWithAuth() the first time, this is the
4526 // request we should be issuing -- the final header line contains the
4527 // proxy's credentials.
4528 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:234529 MockWrite(
4530 "GET http://www.example.org/ HTTP/1.1\r\n"
4531 "Host: www.example.org\r\n"
4532 "Proxy-Connection: keep-alive\r\n"
4533 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164534 };
4535
4536 // Now the proxy server lets the request pass through to origin server.
4537 // The origin server responds with a 401.
4538 MockRead data_reads2[] = {
4539 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4540 // Note: We are using the same realm-name as the proxy server. This is
4541 // completely valid, as realms are unique across hosts.
4542 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4543 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4544 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064545 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164546 };
4547
4548 // After calling trans->RestartWithAuth() the second time, we should send
4549 // the credentials for both the proxy and origin server.
4550 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:234551 MockWrite(
4552 "GET http://www.example.org/ HTTP/1.1\r\n"
4553 "Host: www.example.org\r\n"
4554 "Proxy-Connection: keep-alive\r\n"
4555 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4556 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164557 };
4558
4559 // Lastly we get the desired content.
4560 MockRead data_reads3[] = {
4561 MockRead("HTTP/1.0 200 OK\r\n"),
4562 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4563 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064564 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164565 };
4566
[email protected]31a2bfe2010-02-09 08:03:394567 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4568 data_writes1, arraysize(data_writes1));
4569 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4570 data_writes2, arraysize(data_writes2));
4571 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4572 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074573 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4574 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4575 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164576
[email protected]49639fa2011-12-20 23:22:414577 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164578
[email protected]49639fa2011-12-20 23:22:414579 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424580 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164581
4582 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424583 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164584
[email protected]1c773ea12009-04-28 19:58:424585 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504586 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044587 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164588
[email protected]49639fa2011-12-20 23:22:414589 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164590
[email protected]49639fa2011-12-20 23:22:414591 rv = trans->RestartWithAuth(
4592 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424593 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164594
4595 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424596 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164597
4598 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504599 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044600 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164601
[email protected]49639fa2011-12-20 23:22:414602 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164603
[email protected]49639fa2011-12-20 23:22:414604 rv = trans->RestartWithAuth(
4605 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424606 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164607
4608 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424609 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164610
4611 response = trans->GetResponseInfo();
4612 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4613 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164614}
[email protected]4ddaf2502008-10-23 18:26:194615
[email protected]ea9dc9a2009-09-05 00:43:324616// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4617// can't hook into its internals to cause it to generate predictable NTLM
4618// authorization headers.
4619#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294620// The NTLM authentication unit tests were generated by capturing the HTTP
4621// requests and responses using Fiddler 2 and inspecting the generated random
4622// bytes in the debugger.
4623
4624// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024625TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424626 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244627 request.method = "GET";
4628 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544629
4630 // Ensure load is not disrupted by flags which suppress behaviour specific
4631 // to other auth schemes.
4632 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244633
[email protected]cb9bf6ca2011-01-28 13:15:274634 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4635 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074636 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274637
[email protected]3f918782009-02-28 01:29:244638 MockWrite data_writes1[] = {
4639 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4640 "Host: 172.22.68.17\r\n"
4641 "Connection: keep-alive\r\n\r\n"),
4642 };
4643
4644 MockRead data_reads1[] = {
4645 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044646 // Negotiate and NTLM are often requested together. However, we only want
4647 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4648 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244649 MockRead("WWW-Authenticate: NTLM\r\n"),
4650 MockRead("Connection: close\r\n"),
4651 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364652 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244653 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064654 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244655 };
4656
4657 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224658 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244659 // request we should be issuing -- the final header line contains a Type
4660 // 1 message.
4661 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4662 "Host: 172.22.68.17\r\n"
4663 "Connection: keep-alive\r\n"
4664 "Authorization: NTLM "
4665 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4666
4667 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4668 // (the credentials for the origin server). The second request continues
4669 // on the same connection.
4670 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4671 "Host: 172.22.68.17\r\n"
4672 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294673 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4674 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4675 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4676 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4677 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244678 };
4679
4680 MockRead data_reads2[] = {
4681 // The origin server responds with a Type 2 message.
4682 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4683 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294684 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244685 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4686 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4687 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4688 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4689 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4690 "BtAAAAAAA=\r\n"),
4691 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364692 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244693 MockRead("You are not authorized to view this page\r\n"),
4694
4695 // Lastly we get the desired content.
4696 MockRead("HTTP/1.1 200 OK\r\n"),
4697 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4698 MockRead("Content-Length: 13\r\n\r\n"),
4699 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064700 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244701 };
4702
[email protected]31a2bfe2010-02-09 08:03:394703 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4704 data_writes1, arraysize(data_writes1));
4705 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4706 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074707 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4708 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244709
[email protected]49639fa2011-12-20 23:22:414710 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244711
[email protected]262eec82013-03-19 21:01:364712 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504713 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504714
[email protected]49639fa2011-12-20 23:22:414715 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424716 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244717
4718 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424719 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244720
[email protected]0757e7702009-03-27 04:00:224721 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4722
[email protected]1c773ea12009-04-28 19:58:424723 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044724 ASSERT_FALSE(response == NULL);
4725 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244726
[email protected]49639fa2011-12-20 23:22:414727 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254728
[email protected]f3cf9802011-10-28 18:44:584729 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414730 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254731 EXPECT_EQ(ERR_IO_PENDING, rv);
4732
4733 rv = callback2.WaitForResult();
4734 EXPECT_EQ(OK, rv);
4735
4736 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4737
4738 response = trans->GetResponseInfo();
4739 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254740 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4741
[email protected]49639fa2011-12-20 23:22:414742 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244743
[email protected]49639fa2011-12-20 23:22:414744 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424745 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244746
[email protected]0757e7702009-03-27 04:00:224747 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424748 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244749
4750 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504751 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244752 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4753 EXPECT_EQ(13, response->headers->GetContentLength());
4754}
4755
[email protected]385a4672009-03-11 22:21:294756// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024757TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424758 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294759 request.method = "GET";
4760 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4761 request.load_flags = 0;
4762
[email protected]cb9bf6ca2011-01-28 13:15:274763 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4764 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074765 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274766
[email protected]385a4672009-03-11 22:21:294767 MockWrite data_writes1[] = {
4768 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4769 "Host: 172.22.68.17\r\n"
4770 "Connection: keep-alive\r\n\r\n"),
4771 };
4772
4773 MockRead data_reads1[] = {
4774 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044775 // Negotiate and NTLM are often requested together. However, we only want
4776 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4777 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294778 MockRead("WWW-Authenticate: NTLM\r\n"),
4779 MockRead("Connection: close\r\n"),
4780 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364781 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294782 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064783 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294784 };
4785
4786 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224787 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294788 // request we should be issuing -- the final header line contains a Type
4789 // 1 message.
4790 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4791 "Host: 172.22.68.17\r\n"
4792 "Connection: keep-alive\r\n"
4793 "Authorization: NTLM "
4794 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4795
4796 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4797 // (the credentials for the origin server). The second request continues
4798 // on the same connection.
4799 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4800 "Host: 172.22.68.17\r\n"
4801 "Connection: keep-alive\r\n"
4802 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4803 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4804 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4805 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4806 "4Ww7b7E=\r\n\r\n"),
4807 };
4808
4809 MockRead data_reads2[] = {
4810 // The origin server responds with a Type 2 message.
4811 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4812 MockRead("WWW-Authenticate: NTLM "
4813 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4814 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4815 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4816 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4817 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4818 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4819 "BtAAAAAAA=\r\n"),
4820 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364821 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294822 MockRead("You are not authorized to view this page\r\n"),
4823
4824 // Wrong password.
4825 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294826 MockRead("WWW-Authenticate: NTLM\r\n"),
4827 MockRead("Connection: close\r\n"),
4828 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364829 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294830 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064831 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294832 };
4833
4834 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224835 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294836 // request we should be issuing -- the final header line contains a Type
4837 // 1 message.
4838 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4839 "Host: 172.22.68.17\r\n"
4840 "Connection: keep-alive\r\n"
4841 "Authorization: NTLM "
4842 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4843
4844 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4845 // (the credentials for the origin server). The second request continues
4846 // on the same connection.
4847 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4848 "Host: 172.22.68.17\r\n"
4849 "Connection: keep-alive\r\n"
4850 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4851 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4852 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4853 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4854 "+4MUm7c=\r\n\r\n"),
4855 };
4856
4857 MockRead data_reads3[] = {
4858 // The origin server responds with a Type 2 message.
4859 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4860 MockRead("WWW-Authenticate: NTLM "
4861 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4862 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4863 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4864 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4865 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4866 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4867 "BtAAAAAAA=\r\n"),
4868 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364869 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294870 MockRead("You are not authorized to view this page\r\n"),
4871
4872 // Lastly we get the desired content.
4873 MockRead("HTTP/1.1 200 OK\r\n"),
4874 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4875 MockRead("Content-Length: 13\r\n\r\n"),
4876 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064877 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294878 };
4879
[email protected]31a2bfe2010-02-09 08:03:394880 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4881 data_writes1, arraysize(data_writes1));
4882 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4883 data_writes2, arraysize(data_writes2));
4884 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4885 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074886 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4887 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4888 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294889
[email protected]49639fa2011-12-20 23:22:414890 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294891
[email protected]262eec82013-03-19 21:01:364892 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504894
[email protected]49639fa2011-12-20 23:22:414895 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424896 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294897
4898 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424899 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294900
[email protected]0757e7702009-03-27 04:00:224901 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294902
[email protected]1c773ea12009-04-28 19:58:424903 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504904 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044905 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294906
[email protected]49639fa2011-12-20 23:22:414907 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294908
[email protected]0757e7702009-03-27 04:00:224909 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584910 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414911 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424912 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294913
[email protected]10af5fe72011-01-31 16:17:254914 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424915 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294916
[email protected]0757e7702009-03-27 04:00:224917 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414918 TestCompletionCallback callback3;
4919 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424920 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254921 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424922 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224923 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4924
4925 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044926 ASSERT_FALSE(response == NULL);
4927 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224928
[email protected]49639fa2011-12-20 23:22:414929 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224930
4931 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584932 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414933 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254934 EXPECT_EQ(ERR_IO_PENDING, rv);
4935
4936 rv = callback4.WaitForResult();
4937 EXPECT_EQ(OK, rv);
4938
4939 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4940
[email protected]49639fa2011-12-20 23:22:414941 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254942
4943 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414944 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424945 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224946
4947 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424948 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224949
[email protected]385a4672009-03-11 22:21:294950 response = trans->GetResponseInfo();
4951 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4952 EXPECT_EQ(13, response->headers->GetContentLength());
4953}
[email protected]ea9dc9a2009-09-05 00:43:324954#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294955
[email protected]4ddaf2502008-10-23 18:26:194956// Test reading a server response which has only headers, and no body.
4957// After some maximum number of bytes is consumed, the transaction should
4958// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024959TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424960 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194961 request.method = "GET";
bncce36dca22015-04-21 22:11:234962 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:194963 request.load_flags = 0;
4964
[email protected]3fe8d2f82013-10-17 08:56:074965 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274966 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414967 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274968
[email protected]b75b7b2f2009-10-06 00:54:534969 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434970 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534971 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194972
4973 MockRead data_reads[] = {
4974 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064975 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194976 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064977 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194978 };
[email protected]31a2bfe2010-02-09 08:03:394979 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074980 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194981
[email protected]49639fa2011-12-20 23:22:414982 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194983
[email protected]49639fa2011-12-20 23:22:414984 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424985 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194986
4987 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424988 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194989}
[email protected]f4e426b2008-11-05 00:24:494990
4991// Make sure that we don't try to reuse a TCPClientSocket when failing to
4992// establish tunnel.
4993// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024994TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234995 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274996 HttpRequestInfo request;
4997 request.method = "GET";
bncce36dca22015-04-21 22:11:234998 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274999 request.load_flags = 0;
5000
[email protected]f4e426b2008-11-05 00:24:495001 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075002 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:015003
[email protected]bb88e1d32013-05-03 23:11:075004 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495005
[email protected]262eec82013-03-19 21:01:365006 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505007 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495008
[email protected]f4e426b2008-11-05 00:24:495009 // Since we have proxy, should try to establish tunnel.
5010 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235011 MockWrite(
5012 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5013 "Host: www.example.org\r\n"
5014 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495015 };
5016
[email protected]77848d12008-11-14 00:00:225017 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495018 // connection. Usually a proxy would return 501 (not implemented),
5019 // or 200 (tunnel established).
5020 MockRead data_reads1[] = {
5021 MockRead("HTTP/1.1 404 Not Found\r\n"),
5022 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065023 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495024 };
5025
[email protected]31a2bfe2010-02-09 08:03:395026 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5027 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075028 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495029
[email protected]49639fa2011-12-20 23:22:415030 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495031
[email protected]49639fa2011-12-20 23:22:415032 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425033 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495034
5035 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425036 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495037
[email protected]b4404c02009-04-10 16:38:525038 // Empty the current queue. This is necessary because idle sockets are
5039 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345040 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525041
[email protected]f4e426b2008-11-05 00:24:495042 // We now check to make sure the TCPClientSocket was not added back to
5043 // the pool.
[email protected]90499482013-06-01 00:39:505044 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495045 trans.reset();
[email protected]2da659e2013-05-23 20:51:345046 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495047 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505048 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495049}
[email protected]372d34a2008-11-05 21:30:515050
[email protected]1b157c02009-04-21 01:55:405051// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025052TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425053 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405054 request.method = "GET";
bncce36dca22015-04-21 22:11:235055 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405056 request.load_flags = 0;
5057
[email protected]bb88e1d32013-05-03 23:11:075058 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275059
[email protected]262eec82013-03-19 21:01:365060 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505061 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275062
[email protected]1b157c02009-04-21 01:55:405063 MockRead data_reads[] = {
5064 // A part of the response body is received with the response headers.
5065 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5066 // The rest of the response body is received in two parts.
5067 MockRead("lo"),
5068 MockRead(" world"),
5069 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065070 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405071 };
5072
[email protected]31a2bfe2010-02-09 08:03:395073 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075074 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405075
[email protected]49639fa2011-12-20 23:22:415076 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405077
[email protected]49639fa2011-12-20 23:22:415078 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425079 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405080
5081 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425082 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405083
[email protected]1c773ea12009-04-28 19:58:425084 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505085 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405086
[email protected]90499482013-06-01 00:39:505087 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405088 std::string status_line = response->headers->GetStatusLine();
5089 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5090
[email protected]90499482013-06-01 00:39:505091 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405092
5093 std::string response_data;
5094 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425095 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405096 EXPECT_EQ("hello world", response_data);
5097
5098 // Empty the current queue. This is necessary because idle sockets are
5099 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345100 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405101
5102 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505103 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405104}
5105
[email protected]76a505b2010-08-25 06:23:005106// Make sure that we recycle a SSL socket after reading all of the response
5107// body.
[email protected]23e482282013-06-14 16:08:025108TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005109 HttpRequestInfo request;
5110 request.method = "GET";
bncce36dca22015-04-21 22:11:235111 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005112 request.load_flags = 0;
5113
5114 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235115 MockWrite(
5116 "GET / HTTP/1.1\r\n"
5117 "Host: www.example.org\r\n"
5118 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005119 };
5120
5121 MockRead data_reads[] = {
5122 MockRead("HTTP/1.1 200 OK\r\n"),
5123 MockRead("Content-Length: 11\r\n\r\n"),
5124 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065125 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005126 };
5127
[email protected]8ddf8322012-02-23 18:08:065128 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075129 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005130
5131 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5132 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075133 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005134
[email protected]49639fa2011-12-20 23:22:415135 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005136
[email protected]bb88e1d32013-05-03 23:11:075137 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365138 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505139 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005140
[email protected]49639fa2011-12-20 23:22:415141 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005142
5143 EXPECT_EQ(ERR_IO_PENDING, rv);
5144 EXPECT_EQ(OK, callback.WaitForResult());
5145
5146 const HttpResponseInfo* response = trans->GetResponseInfo();
5147 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505148 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005149 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5150
[email protected]90499482013-06-01 00:39:505151 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005152
5153 std::string response_data;
5154 rv = ReadTransaction(trans.get(), &response_data);
5155 EXPECT_EQ(OK, rv);
5156 EXPECT_EQ("hello world", response_data);
5157
5158 // Empty the current queue. This is necessary because idle sockets are
5159 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345160 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005161
5162 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505163 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005164}
5165
5166// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5167// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025168TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005169 HttpRequestInfo request;
5170 request.method = "GET";
bncce36dca22015-04-21 22:11:235171 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005172 request.load_flags = 0;
5173
5174 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235175 MockWrite(
5176 "GET / HTTP/1.1\r\n"
5177 "Host: www.example.org\r\n"
5178 "Connection: keep-alive\r\n\r\n"),
5179 MockWrite(
5180 "GET / HTTP/1.1\r\n"
5181 "Host: www.example.org\r\n"
5182 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005183 };
5184
5185 MockRead data_reads[] = {
5186 MockRead("HTTP/1.1 200 OK\r\n"),
5187 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065188 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005189 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065190 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005191 };
5192
[email protected]8ddf8322012-02-23 18:08:065193 SSLSocketDataProvider ssl(ASYNC, OK);
5194 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075195 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5196 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005197
5198 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5199 data_writes, arraysize(data_writes));
5200 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5201 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075202 session_deps_.socket_factory->AddSocketDataProvider(&data);
5203 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005204
[email protected]49639fa2011-12-20 23:22:415205 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005206
[email protected]bb88e1d32013-05-03 23:11:075207 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365208 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005210
[email protected]49639fa2011-12-20 23:22:415211 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005212
5213 EXPECT_EQ(ERR_IO_PENDING, rv);
5214 EXPECT_EQ(OK, callback.WaitForResult());
5215
5216 const HttpResponseInfo* response = trans->GetResponseInfo();
5217 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505218 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005219 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5220
[email protected]90499482013-06-01 00:39:505221 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005222
5223 std::string response_data;
5224 rv = ReadTransaction(trans.get(), &response_data);
5225 EXPECT_EQ(OK, rv);
5226 EXPECT_EQ("hello world", response_data);
5227
5228 // Empty the current queue. This is necessary because idle sockets are
5229 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345230 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005231
5232 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505233 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005234
5235 // Now start the second transaction, which should reuse the previous socket.
5236
[email protected]90499482013-06-01 00:39:505237 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005238
[email protected]49639fa2011-12-20 23:22:415239 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005240
5241 EXPECT_EQ(ERR_IO_PENDING, rv);
5242 EXPECT_EQ(OK, callback.WaitForResult());
5243
5244 response = trans->GetResponseInfo();
5245 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505246 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005247 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5248
[email protected]90499482013-06-01 00:39:505249 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005250
5251 rv = ReadTransaction(trans.get(), &response_data);
5252 EXPECT_EQ(OK, rv);
5253 EXPECT_EQ("hello world", response_data);
5254
5255 // Empty the current queue. This is necessary because idle sockets are
5256 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345257 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005258
5259 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505260 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005261}
5262
[email protected]b4404c02009-04-10 16:38:525263// Make sure that we recycle a socket after a zero-length response.
5264// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025265TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425266 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525267 request.method = "GET";
bncce36dca22015-04-21 22:11:235268 request.url = GURL(
5269 "http://www.example.org/csi?v=3&s=web&action=&"
5270 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5271 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5272 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525273 request.load_flags = 0;
5274
[email protected]bb88e1d32013-05-03 23:11:075275 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275276
[email protected]262eec82013-03-19 21:01:365277 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505278 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275279
[email protected]b4404c02009-04-10 16:38:525280 MockRead data_reads[] = {
5281 MockRead("HTTP/1.1 204 No Content\r\n"
5282 "Content-Length: 0\r\n"
5283 "Content-Type: text/html\r\n\r\n"),
5284 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065285 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525286 };
5287
[email protected]31a2bfe2010-02-09 08:03:395288 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075289 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525290
[email protected]49639fa2011-12-20 23:22:415291 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525292
[email protected]49639fa2011-12-20 23:22:415293 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425294 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525295
5296 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425297 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525298
[email protected]1c773ea12009-04-28 19:58:425299 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505300 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525301
[email protected]90499482013-06-01 00:39:505302 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525303 std::string status_line = response->headers->GetStatusLine();
5304 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5305
[email protected]90499482013-06-01 00:39:505306 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525307
5308 std::string response_data;
5309 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425310 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525311 EXPECT_EQ("", response_data);
5312
5313 // Empty the current queue. This is necessary because idle sockets are
5314 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345315 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525316
5317 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505318 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525319}
5320
[email protected]23e482282013-06-14 16:08:025321TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065322 ScopedVector<UploadElementReader> element_readers;
5323 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075324 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275325
[email protected]1c773ea12009-04-28 19:58:425326 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515327 // Transaction 1: a GET request that succeeds. The socket is recycled
5328 // after use.
5329 request[0].method = "GET";
5330 request[0].url = GURL("http://www.google.com/");
5331 request[0].load_flags = 0;
5332 // Transaction 2: a POST request. Reuses the socket kept alive from
5333 // transaction 1. The first attempts fails when writing the POST data.
5334 // This causes the transaction to retry with a new socket. The second
5335 // attempt succeeds.
5336 request[1].method = "POST";
5337 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275338 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515339 request[1].load_flags = 0;
5340
[email protected]bb88e1d32013-05-03 23:11:075341 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515342
5343 // The first socket is used for transaction 1 and the first attempt of
5344 // transaction 2.
5345
5346 // The response of transaction 1.
5347 MockRead data_reads1[] = {
5348 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5349 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065350 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515351 };
5352 // The mock write results of transaction 1 and the first attempt of
5353 // transaction 2.
5354 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065355 MockWrite(SYNCHRONOUS, 64), // GET
5356 MockWrite(SYNCHRONOUS, 93), // POST
5357 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515358 };
[email protected]31a2bfe2010-02-09 08:03:395359 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5360 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515361
5362 // The second socket is used for the second attempt of transaction 2.
5363
5364 // The response of transaction 2.
5365 MockRead data_reads2[] = {
5366 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5367 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065368 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515369 };
5370 // The mock write results of the second attempt of transaction 2.
5371 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065372 MockWrite(SYNCHRONOUS, 93), // POST
5373 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515374 };
[email protected]31a2bfe2010-02-09 08:03:395375 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5376 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515377
[email protected]bb88e1d32013-05-03 23:11:075378 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5379 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515380
thestig9d3bb0c2015-01-24 00:49:515381 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515382 "hello world", "welcome"
5383 };
5384
5385 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425386 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505387 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515388
[email protected]49639fa2011-12-20 23:22:415389 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515390
[email protected]49639fa2011-12-20 23:22:415391 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425392 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515393
5394 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425395 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515396
[email protected]1c773ea12009-04-28 19:58:425397 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505398 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515399
[email protected]90499482013-06-01 00:39:505400 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515401 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5402
5403 std::string response_data;
5404 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425405 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515406 EXPECT_EQ(kExpectedResponseData[i], response_data);
5407 }
5408}
[email protected]f9ee6b52008-11-08 06:46:235409
5410// Test the request-challenge-retry sequence for basic auth when there is
5411// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165412// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025413TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425414 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235415 request.method = "GET";
bncce36dca22015-04-21 22:11:235416 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415417 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295418
[email protected]3fe8d2f82013-10-17 08:56:075419 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275420 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415421 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275422
[email protected]a97cca42009-08-14 01:00:295423 // The password contains an escaped character -- for this test to pass it
5424 // will need to be unescaped by HttpNetworkTransaction.
5425 EXPECT_EQ("b%40r", request.url.password());
5426
[email protected]f9ee6b52008-11-08 06:46:235427 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235428 MockWrite(
5429 "GET / HTTP/1.1\r\n"
5430 "Host: www.example.org\r\n"
5431 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235432 };
5433
5434 MockRead data_reads1[] = {
5435 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5436 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5437 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065438 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235439 };
5440
[email protected]2262e3a2012-05-22 16:08:165441 // After the challenge above, the transaction will be restarted using the
5442 // identity from the url (foo, b@r) to answer the challenge.
5443 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235444 MockWrite(
5445 "GET / HTTP/1.1\r\n"
5446 "Host: www.example.org\r\n"
5447 "Connection: keep-alive\r\n"
5448 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165449 };
5450
5451 MockRead data_reads2[] = {
5452 MockRead("HTTP/1.0 200 OK\r\n"),
5453 MockRead("Content-Length: 100\r\n\r\n"),
5454 MockRead(SYNCHRONOUS, OK),
5455 };
5456
[email protected]31a2bfe2010-02-09 08:03:395457 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5458 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165459 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5460 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075461 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5462 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235463
[email protected]49639fa2011-12-20 23:22:415464 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415465 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425466 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235467 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425468 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165469 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5470
5471 TestCompletionCallback callback2;
5472 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5473 EXPECT_EQ(ERR_IO_PENDING, rv);
5474 rv = callback2.WaitForResult();
5475 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225476 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5477
[email protected]2262e3a2012-05-22 16:08:165478 const HttpResponseInfo* response = trans->GetResponseInfo();
5479 ASSERT_TRUE(response != NULL);
5480
5481 // There is no challenge info, since the identity in URL worked.
5482 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5483
5484 EXPECT_EQ(100, response->headers->GetContentLength());
5485
5486 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345487 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165488}
5489
5490// Test the request-challenge-retry sequence for basic auth when there is an
5491// incorrect identity in the URL. The identity from the URL should be used only
5492// once.
[email protected]23e482282013-06-14 16:08:025493TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165494 HttpRequestInfo request;
5495 request.method = "GET";
5496 // Note: the URL has a username:password in it. The password "baz" is
5497 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:235498 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:165499
5500 request.load_flags = LOAD_NORMAL;
5501
[email protected]3fe8d2f82013-10-17 08:56:075502 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165503 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415504 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165505
5506 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235507 MockWrite(
5508 "GET / HTTP/1.1\r\n"
5509 "Host: www.example.org\r\n"
5510 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165511 };
5512
5513 MockRead data_reads1[] = {
5514 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5515 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5516 MockRead("Content-Length: 10\r\n\r\n"),
5517 MockRead(SYNCHRONOUS, ERR_FAILED),
5518 };
5519
5520 // After the challenge above, the transaction will be restarted using the
5521 // identity from the url (foo, baz) to answer the challenge.
5522 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235523 MockWrite(
5524 "GET / HTTP/1.1\r\n"
5525 "Host: www.example.org\r\n"
5526 "Connection: keep-alive\r\n"
5527 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165528 };
5529
5530 MockRead data_reads2[] = {
5531 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5532 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5533 MockRead("Content-Length: 10\r\n\r\n"),
5534 MockRead(SYNCHRONOUS, ERR_FAILED),
5535 };
5536
5537 // After the challenge above, the transaction will be restarted using the
5538 // identity supplied by the user (foo, bar) to answer the challenge.
5539 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235540 MockWrite(
5541 "GET / HTTP/1.1\r\n"
5542 "Host: www.example.org\r\n"
5543 "Connection: keep-alive\r\n"
5544 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165545 };
5546
5547 MockRead data_reads3[] = {
5548 MockRead("HTTP/1.0 200 OK\r\n"),
5549 MockRead("Content-Length: 100\r\n\r\n"),
5550 MockRead(SYNCHRONOUS, OK),
5551 };
5552
5553 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5554 data_writes1, arraysize(data_writes1));
5555 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5556 data_writes2, arraysize(data_writes2));
5557 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5558 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075559 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5560 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5561 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165562
5563 TestCompletionCallback callback1;
5564
5565 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5566 EXPECT_EQ(ERR_IO_PENDING, rv);
5567
5568 rv = callback1.WaitForResult();
5569 EXPECT_EQ(OK, rv);
5570
5571 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5572 TestCompletionCallback callback2;
5573 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5574 EXPECT_EQ(ERR_IO_PENDING, rv);
5575 rv = callback2.WaitForResult();
5576 EXPECT_EQ(OK, rv);
5577 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5578
5579 const HttpResponseInfo* response = trans->GetResponseInfo();
5580 ASSERT_TRUE(response != NULL);
5581 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5582
5583 TestCompletionCallback callback3;
5584 rv = trans->RestartWithAuth(
5585 AuthCredentials(kFoo, kBar), callback3.callback());
5586 EXPECT_EQ(ERR_IO_PENDING, rv);
5587 rv = callback3.WaitForResult();
5588 EXPECT_EQ(OK, rv);
5589 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5590
5591 response = trans->GetResponseInfo();
5592 ASSERT_TRUE(response != NULL);
5593
5594 // There is no challenge info, since the identity worked.
5595 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5596
5597 EXPECT_EQ(100, response->headers->GetContentLength());
5598
[email protected]ea9dc9a2009-09-05 00:43:325599 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345600 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325601}
5602
[email protected]2217aa22013-10-11 03:03:545603
5604// Test the request-challenge-retry sequence for basic auth when there is a
5605// correct identity in the URL, but its use is being suppressed. The identity
5606// from the URL should never be used.
5607TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5608 HttpRequestInfo request;
5609 request.method = "GET";
bncce36dca22015-04-21 22:11:235610 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:545611 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5612
[email protected]3fe8d2f82013-10-17 08:56:075613 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545614 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415615 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545616
5617 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235618 MockWrite(
5619 "GET / HTTP/1.1\r\n"
5620 "Host: www.example.org\r\n"
5621 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545622 };
5623
5624 MockRead data_reads1[] = {
5625 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5626 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5627 MockRead("Content-Length: 10\r\n\r\n"),
5628 MockRead(SYNCHRONOUS, ERR_FAILED),
5629 };
5630
5631 // After the challenge above, the transaction will be restarted using the
5632 // identity supplied by the user, not the one in the URL, to answer the
5633 // challenge.
5634 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235635 MockWrite(
5636 "GET / HTTP/1.1\r\n"
5637 "Host: www.example.org\r\n"
5638 "Connection: keep-alive\r\n"
5639 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545640 };
5641
5642 MockRead data_reads3[] = {
5643 MockRead("HTTP/1.0 200 OK\r\n"),
5644 MockRead("Content-Length: 100\r\n\r\n"),
5645 MockRead(SYNCHRONOUS, OK),
5646 };
5647
5648 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5649 data_writes1, arraysize(data_writes1));
5650 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5651 data_writes3, arraysize(data_writes3));
5652 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5653 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5654
5655 TestCompletionCallback callback1;
5656 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5657 EXPECT_EQ(ERR_IO_PENDING, rv);
5658 rv = callback1.WaitForResult();
5659 EXPECT_EQ(OK, rv);
5660 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5661
5662 const HttpResponseInfo* response = trans->GetResponseInfo();
5663 ASSERT_TRUE(response != NULL);
5664 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5665
5666 TestCompletionCallback callback3;
5667 rv = trans->RestartWithAuth(
5668 AuthCredentials(kFoo, kBar), callback3.callback());
5669 EXPECT_EQ(ERR_IO_PENDING, rv);
5670 rv = callback3.WaitForResult();
5671 EXPECT_EQ(OK, rv);
5672 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5673
5674 response = trans->GetResponseInfo();
5675 ASSERT_TRUE(response != NULL);
5676
5677 // There is no challenge info, since the identity worked.
5678 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5679 EXPECT_EQ(100, response->headers->GetContentLength());
5680
5681 // Empty the current queue.
5682 base::MessageLoop::current()->RunUntilIdle();
5683}
5684
[email protected]f9ee6b52008-11-08 06:46:235685// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025686TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075687 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235688
5689 // Transaction 1: authenticate (foo, bar) on MyRealm1
5690 {
[email protected]1c773ea12009-04-28 19:58:425691 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235692 request.method = "GET";
bncce36dca22015-04-21 22:11:235693 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:235694 request.load_flags = 0;
5695
[email protected]262eec82013-03-19 21:01:365696 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505697 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275698
[email protected]f9ee6b52008-11-08 06:46:235699 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235700 MockWrite(
5701 "GET /x/y/z HTTP/1.1\r\n"
5702 "Host: www.example.org\r\n"
5703 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235704 };
5705
5706 MockRead data_reads1[] = {
5707 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5708 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5709 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065710 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235711 };
5712
5713 // Resend with authorization (username=foo, password=bar)
5714 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235715 MockWrite(
5716 "GET /x/y/z HTTP/1.1\r\n"
5717 "Host: www.example.org\r\n"
5718 "Connection: keep-alive\r\n"
5719 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235720 };
5721
5722 // Sever accepts the authorization.
5723 MockRead data_reads2[] = {
5724 MockRead("HTTP/1.0 200 OK\r\n"),
5725 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065726 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235727 };
5728
[email protected]31a2bfe2010-02-09 08:03:395729 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5730 data_writes1, arraysize(data_writes1));
5731 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5732 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075733 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5734 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235735
[email protected]49639fa2011-12-20 23:22:415736 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235737
[email protected]49639fa2011-12-20 23:22:415738 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425739 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235740
5741 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425742 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235743
[email protected]1c773ea12009-04-28 19:58:425744 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505745 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045746 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235747
[email protected]49639fa2011-12-20 23:22:415748 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235749
[email protected]49639fa2011-12-20 23:22:415750 rv = trans->RestartWithAuth(
5751 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425752 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235753
5754 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425755 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235756
5757 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505758 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235759 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5760 EXPECT_EQ(100, response->headers->GetContentLength());
5761 }
5762
5763 // ------------------------------------------------------------------------
5764
5765 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5766 {
[email protected]1c773ea12009-04-28 19:58:425767 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235768 request.method = "GET";
5769 // Note that Transaction 1 was at /x/y/z, so this is in the same
5770 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:235771 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:235772 request.load_flags = 0;
5773
[email protected]262eec82013-03-19 21:01:365774 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505775 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275776
[email protected]f9ee6b52008-11-08 06:46:235777 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235778 MockWrite(
5779 "GET /x/y/a/b HTTP/1.1\r\n"
5780 "Host: www.example.org\r\n"
5781 "Connection: keep-alive\r\n"
5782 // Send preemptive authorization for MyRealm1
5783 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235784 };
5785
5786 // The server didn't like the preemptive authorization, and
5787 // challenges us for a different realm (MyRealm2).
5788 MockRead data_reads1[] = {
5789 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5790 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5791 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065792 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235793 };
5794
5795 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5796 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235797 MockWrite(
5798 "GET /x/y/a/b HTTP/1.1\r\n"
5799 "Host: www.example.org\r\n"
5800 "Connection: keep-alive\r\n"
5801 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235802 };
5803
5804 // Sever accepts the authorization.
5805 MockRead data_reads2[] = {
5806 MockRead("HTTP/1.0 200 OK\r\n"),
5807 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065808 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235809 };
5810
[email protected]31a2bfe2010-02-09 08:03:395811 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5812 data_writes1, arraysize(data_writes1));
5813 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5814 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075815 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5816 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235817
[email protected]49639fa2011-12-20 23:22:415818 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235819
[email protected]49639fa2011-12-20 23:22:415820 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425821 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235822
5823 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425824 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235825
[email protected]1c773ea12009-04-28 19:58:425826 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505827 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045828 ASSERT_TRUE(response->auth_challenge.get());
5829 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:235830 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:045831 response->auth_challenge->challenger.ToString());
5832 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5833 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235834
[email protected]49639fa2011-12-20 23:22:415835 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235836
[email protected]49639fa2011-12-20 23:22:415837 rv = trans->RestartWithAuth(
5838 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425839 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235840
5841 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425842 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235843
5844 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505845 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235846 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5847 EXPECT_EQ(100, response->headers->GetContentLength());
5848 }
5849
5850 // ------------------------------------------------------------------------
5851
5852 // Transaction 3: Resend a request in MyRealm's protection space --
5853 // succeed with preemptive authorization.
5854 {
[email protected]1c773ea12009-04-28 19:58:425855 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235856 request.method = "GET";
bncce36dca22015-04-21 22:11:235857 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:235858 request.load_flags = 0;
5859
[email protected]262eec82013-03-19 21:01:365860 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505861 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275862
[email protected]f9ee6b52008-11-08 06:46:235863 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235864 MockWrite(
5865 "GET /x/y/z2 HTTP/1.1\r\n"
5866 "Host: www.example.org\r\n"
5867 "Connection: keep-alive\r\n"
5868 // The authorization for MyRealm1 gets sent preemptively
5869 // (since the url is in the same protection space)
5870 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235871 };
5872
5873 // Sever accepts the preemptive authorization
5874 MockRead data_reads1[] = {
5875 MockRead("HTTP/1.0 200 OK\r\n"),
5876 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065877 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235878 };
5879
[email protected]31a2bfe2010-02-09 08:03:395880 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5881 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075882 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235883
[email protected]49639fa2011-12-20 23:22:415884 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235885
[email protected]49639fa2011-12-20 23:22:415886 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425887 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235888
5889 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425890 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235891
[email protected]1c773ea12009-04-28 19:58:425892 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505893 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235894
5895 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5896 EXPECT_EQ(100, response->headers->GetContentLength());
5897 }
5898
5899 // ------------------------------------------------------------------------
5900
5901 // Transaction 4: request another URL in MyRealm (however the
5902 // url is not known to belong to the protection space, so no pre-auth).
5903 {
[email protected]1c773ea12009-04-28 19:58:425904 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235905 request.method = "GET";
bncce36dca22015-04-21 22:11:235906 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:235907 request.load_flags = 0;
5908
[email protected]262eec82013-03-19 21:01:365909 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505910 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275911
[email protected]f9ee6b52008-11-08 06:46:235912 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235913 MockWrite(
5914 "GET /x/1 HTTP/1.1\r\n"
5915 "Host: www.example.org\r\n"
5916 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235917 };
5918
5919 MockRead data_reads1[] = {
5920 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5921 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5922 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065923 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235924 };
5925
5926 // Resend with authorization from MyRealm's cache.
5927 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235928 MockWrite(
5929 "GET /x/1 HTTP/1.1\r\n"
5930 "Host: www.example.org\r\n"
5931 "Connection: keep-alive\r\n"
5932 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235933 };
5934
5935 // Sever accepts the authorization.
5936 MockRead data_reads2[] = {
5937 MockRead("HTTP/1.0 200 OK\r\n"),
5938 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065939 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235940 };
5941
[email protected]31a2bfe2010-02-09 08:03:395942 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5943 data_writes1, arraysize(data_writes1));
5944 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5945 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075946 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5947 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235948
[email protected]49639fa2011-12-20 23:22:415949 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235950
[email protected]49639fa2011-12-20 23:22:415951 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425952 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235953
5954 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425955 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235956
[email protected]0757e7702009-03-27 04:00:225957 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415958 TestCompletionCallback callback2;
5959 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425960 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225961 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425962 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225963 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5964
[email protected]1c773ea12009-04-28 19:58:425965 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505966 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235967 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5968 EXPECT_EQ(100, response->headers->GetContentLength());
5969 }
5970
5971 // ------------------------------------------------------------------------
5972
5973 // Transaction 5: request a URL in MyRealm, but the server rejects the
5974 // cached identity. Should invalidate and re-prompt.
5975 {
[email protected]1c773ea12009-04-28 19:58:425976 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235977 request.method = "GET";
bncce36dca22015-04-21 22:11:235978 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:235979 request.load_flags = 0;
5980
[email protected]262eec82013-03-19 21:01:365981 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505982 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275983
[email protected]f9ee6b52008-11-08 06:46:235984 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235985 MockWrite(
5986 "GET /p/q/t HTTP/1.1\r\n"
5987 "Host: www.example.org\r\n"
5988 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235989 };
5990
5991 MockRead data_reads1[] = {
5992 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5993 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5994 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065995 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235996 };
5997
5998 // Resend with authorization from cache for MyRealm.
5999 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236000 MockWrite(
6001 "GET /p/q/t HTTP/1.1\r\n"
6002 "Host: www.example.org\r\n"
6003 "Connection: keep-alive\r\n"
6004 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236005 };
6006
6007 // Sever rejects the authorization.
6008 MockRead data_reads2[] = {
6009 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6010 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6011 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066012 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236013 };
6014
6015 // At this point we should prompt for new credentials for MyRealm.
6016 // Restart with username=foo3, password=foo4.
6017 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236018 MockWrite(
6019 "GET /p/q/t HTTP/1.1\r\n"
6020 "Host: www.example.org\r\n"
6021 "Connection: keep-alive\r\n"
6022 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236023 };
6024
6025 // Sever accepts the authorization.
6026 MockRead data_reads3[] = {
6027 MockRead("HTTP/1.0 200 OK\r\n"),
6028 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066029 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236030 };
6031
[email protected]31a2bfe2010-02-09 08:03:396032 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6033 data_writes1, arraysize(data_writes1));
6034 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6035 data_writes2, arraysize(data_writes2));
6036 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6037 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076038 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6039 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6040 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236041
[email protected]49639fa2011-12-20 23:22:416042 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236043
[email protected]49639fa2011-12-20 23:22:416044 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426045 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236046
6047 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426048 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236049
[email protected]0757e7702009-03-27 04:00:226050 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416051 TestCompletionCallback callback2;
6052 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426053 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226054 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426055 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226056 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6057
[email protected]1c773ea12009-04-28 19:58:426058 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506059 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046060 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236061
[email protected]49639fa2011-12-20 23:22:416062 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236063
[email protected]49639fa2011-12-20 23:22:416064 rv = trans->RestartWithAuth(
6065 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426066 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236067
[email protected]0757e7702009-03-27 04:00:226068 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426069 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236070
6071 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506072 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236073 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6074 EXPECT_EQ(100, response->headers->GetContentLength());
6075 }
6076}
[email protected]89ceba9a2009-03-21 03:46:066077
[email protected]3c32c5f2010-05-18 15:18:126078// Tests that nonce count increments when multiple auth attempts
6079// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026080TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446081 HttpAuthHandlerDigest::Factory* digest_factory =
6082 new HttpAuthHandlerDigest::Factory();
6083 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6084 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6085 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076086 session_deps_.http_auth_handler_factory.reset(digest_factory);
6087 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126088
6089 // Transaction 1: authenticate (foo, bar) on MyRealm1
6090 {
[email protected]3c32c5f2010-05-18 15:18:126091 HttpRequestInfo request;
6092 request.method = "GET";
bncce36dca22015-04-21 22:11:236093 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126094 request.load_flags = 0;
6095
[email protected]262eec82013-03-19 21:01:366096 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506097 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276098
[email protected]3c32c5f2010-05-18 15:18:126099 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236100 MockWrite(
6101 "GET /x/y/z HTTP/1.1\r\n"
6102 "Host: www.example.org\r\n"
6103 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126104 };
6105
6106 MockRead data_reads1[] = {
6107 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6108 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6109 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066110 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126111 };
6112
6113 // Resend with authorization (username=foo, password=bar)
6114 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236115 MockWrite(
6116 "GET /x/y/z HTTP/1.1\r\n"
6117 "Host: www.example.org\r\n"
6118 "Connection: keep-alive\r\n"
6119 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6120 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6121 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6122 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126123 };
6124
6125 // Sever accepts the authorization.
6126 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:086127 MockRead("HTTP/1.0 200 OK\r\n"),
6128 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126129 };
6130
6131 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6132 data_writes1, arraysize(data_writes1));
6133 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6134 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076135 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6136 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126137
[email protected]49639fa2011-12-20 23:22:416138 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126139
[email protected]49639fa2011-12-20 23:22:416140 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126141 EXPECT_EQ(ERR_IO_PENDING, rv);
6142
6143 rv = callback1.WaitForResult();
6144 EXPECT_EQ(OK, rv);
6145
6146 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506147 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046148 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126149
[email protected]49639fa2011-12-20 23:22:416150 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126151
[email protected]49639fa2011-12-20 23:22:416152 rv = trans->RestartWithAuth(
6153 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126154 EXPECT_EQ(ERR_IO_PENDING, rv);
6155
6156 rv = callback2.WaitForResult();
6157 EXPECT_EQ(OK, rv);
6158
6159 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506160 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126161 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6162 }
6163
6164 // ------------------------------------------------------------------------
6165
6166 // Transaction 2: Request another resource in digestive's protection space.
6167 // This will preemptively add an Authorization header which should have an
6168 // "nc" value of 2 (as compared to 1 in the first use.
6169 {
[email protected]3c32c5f2010-05-18 15:18:126170 HttpRequestInfo request;
6171 request.method = "GET";
6172 // Note that Transaction 1 was at /x/y/z, so this is in the same
6173 // protection space as digest.
bncce36dca22015-04-21 22:11:236174 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126175 request.load_flags = 0;
6176
[email protected]262eec82013-03-19 21:01:366177 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506178 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276179
[email protected]3c32c5f2010-05-18 15:18:126180 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236181 MockWrite(
6182 "GET /x/y/a/b HTTP/1.1\r\n"
6183 "Host: www.example.org\r\n"
6184 "Connection: keep-alive\r\n"
6185 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6186 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6187 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6188 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126189 };
6190
6191 // Sever accepts the authorization.
6192 MockRead data_reads1[] = {
6193 MockRead("HTTP/1.0 200 OK\r\n"),
6194 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066195 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126196 };
6197
6198 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6199 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076200 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126201
[email protected]49639fa2011-12-20 23:22:416202 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126203
[email protected]49639fa2011-12-20 23:22:416204 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126205 EXPECT_EQ(ERR_IO_PENDING, rv);
6206
6207 rv = callback1.WaitForResult();
6208 EXPECT_EQ(OK, rv);
6209
6210 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506211 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126212 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6213 }
6214}
6215
[email protected]89ceba9a2009-03-21 03:46:066216// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026217TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066218 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:076219 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406220 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416221 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066222
6223 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066224 trans->read_buf_ = new IOBuffer(15);
6225 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206226 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066227
6228 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146229 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576230 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086231 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576232 response->response_time = base::Time::Now();
6233 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066234
6235 { // Setup state for response_.vary_data
6236 HttpRequestInfo request;
6237 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6238 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276239 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436240 request.extra_headers.SetHeader("Foo", "1");
6241 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506242 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066243 }
6244
6245 // Cause the above state to be reset.
6246 trans->ResetStateForRestart();
6247
6248 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076249 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066250 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206251 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576252 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6253 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046254 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086255 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576256 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066257}
6258
[email protected]bacff652009-03-31 17:50:336259// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026260TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336261 HttpRequestInfo request;
6262 request.method = "GET";
bncce36dca22015-04-21 22:11:236263 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336264 request.load_flags = 0;
6265
[email protected]3fe8d2f82013-10-17 08:56:076266 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276267 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416268 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276269
[email protected]bacff652009-03-31 17:50:336270 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236271 MockWrite(
6272 "GET / HTTP/1.1\r\n"
6273 "Host: www.example.org\r\n"
6274 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336275 };
6276
6277 MockRead data_reads[] = {
6278 MockRead("HTTP/1.0 200 OK\r\n"),
6279 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6280 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066281 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336282 };
6283
[email protected]5ecc992a42009-11-11 01:41:596284 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396285 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6286 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066287 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6288 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336289
[email protected]bb88e1d32013-05-03 23:11:076290 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6291 session_deps_.socket_factory->AddSocketDataProvider(&data);
6292 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6293 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336294
[email protected]49639fa2011-12-20 23:22:416295 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336296
[email protected]49639fa2011-12-20 23:22:416297 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336298 EXPECT_EQ(ERR_IO_PENDING, rv);
6299
6300 rv = callback.WaitForResult();
6301 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6302
[email protected]49639fa2011-12-20 23:22:416303 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336304 EXPECT_EQ(ERR_IO_PENDING, rv);
6305
6306 rv = callback.WaitForResult();
6307 EXPECT_EQ(OK, rv);
6308
6309 const HttpResponseInfo* response = trans->GetResponseInfo();
6310
[email protected]fe2255a2011-09-20 19:37:506311 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336312 EXPECT_EQ(100, response->headers->GetContentLength());
6313}
6314
6315// Test HTTPS connections to a site with a bad certificate, going through a
6316// proxy
[email protected]23e482282013-06-14 16:08:026317TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:076318 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:336319
6320 HttpRequestInfo request;
6321 request.method = "GET";
bncce36dca22015-04-21 22:11:236322 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336323 request.load_flags = 0;
6324
6325 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:236326 MockWrite(
6327 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6328 "Host: www.example.org\r\n"
6329 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336330 };
6331
6332 MockRead proxy_reads[] = {
6333 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066334 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336335 };
6336
6337 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236338 MockWrite(
6339 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6340 "Host: www.example.org\r\n"
6341 "Proxy-Connection: keep-alive\r\n\r\n"),
6342 MockWrite(
6343 "GET / HTTP/1.1\r\n"
6344 "Host: www.example.org\r\n"
6345 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336346 };
6347
6348 MockRead data_reads[] = {
6349 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6350 MockRead("HTTP/1.0 200 OK\r\n"),
6351 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6352 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066353 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336354 };
6355
[email protected]31a2bfe2010-02-09 08:03:396356 StaticSocketDataProvider ssl_bad_certificate(
6357 proxy_reads, arraysize(proxy_reads),
6358 proxy_writes, arraysize(proxy_writes));
6359 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6360 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066361 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6362 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336363
[email protected]bb88e1d32013-05-03 23:11:076364 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6365 session_deps_.socket_factory->AddSocketDataProvider(&data);
6366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336368
[email protected]49639fa2011-12-20 23:22:416369 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336370
6371 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076372 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336373
[email protected]3fe8d2f82013-10-17 08:56:076374 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406375 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416376 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336377
[email protected]49639fa2011-12-20 23:22:416378 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336379 EXPECT_EQ(ERR_IO_PENDING, rv);
6380
6381 rv = callback.WaitForResult();
6382 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6383
[email protected]49639fa2011-12-20 23:22:416384 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336385 EXPECT_EQ(ERR_IO_PENDING, rv);
6386
6387 rv = callback.WaitForResult();
6388 EXPECT_EQ(OK, rv);
6389
6390 const HttpResponseInfo* response = trans->GetResponseInfo();
6391
[email protected]fe2255a2011-09-20 19:37:506392 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336393 EXPECT_EQ(100, response->headers->GetContentLength());
6394 }
6395}
6396
[email protected]2df19bb2010-08-25 20:13:466397
6398// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026399TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076400 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206401 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516402 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076403 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466404
6405 HttpRequestInfo request;
6406 request.method = "GET";
bncce36dca22015-04-21 22:11:236407 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466408 request.load_flags = 0;
6409
6410 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236411 MockWrite(
6412 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6413 "Host: www.example.org\r\n"
6414 "Proxy-Connection: keep-alive\r\n\r\n"),
6415 MockWrite(
6416 "GET / HTTP/1.1\r\n"
6417 "Host: www.example.org\r\n"
6418 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466419 };
6420
6421 MockRead data_reads[] = {
6422 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6423 MockRead("HTTP/1.1 200 OK\r\n"),
6424 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6425 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066426 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466427 };
6428
6429 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6430 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066431 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6432 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466433
[email protected]bb88e1d32013-05-03 23:11:076434 session_deps_.socket_factory->AddSocketDataProvider(&data);
6435 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6436 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466437
[email protected]49639fa2011-12-20 23:22:416438 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466439
[email protected]3fe8d2f82013-10-17 08:56:076440 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466441 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416442 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466443
[email protected]49639fa2011-12-20 23:22:416444 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466445 EXPECT_EQ(ERR_IO_PENDING, rv);
6446
6447 rv = callback.WaitForResult();
6448 EXPECT_EQ(OK, rv);
6449 const HttpResponseInfo* response = trans->GetResponseInfo();
6450
[email protected]fe2255a2011-09-20 19:37:506451 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466452
6453 EXPECT_TRUE(response->headers->IsKeepAlive());
6454 EXPECT_EQ(200, response->headers->response_code());
6455 EXPECT_EQ(100, response->headers->GetContentLength());
6456 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206457
6458 LoadTimingInfo load_timing_info;
6459 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6460 TestLoadTimingNotReusedWithPac(load_timing_info,
6461 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466462}
6463
[email protected]511f6f52010-12-17 03:58:296464// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026465TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076466 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206467 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516468 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076469 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296470
6471 HttpRequestInfo request;
6472 request.method = "GET";
bncce36dca22015-04-21 22:11:236473 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296474 request.load_flags = 0;
6475
6476 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236477 MockWrite(
6478 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6479 "Host: www.example.org\r\n"
6480 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296481 };
6482
6483 MockRead data_reads[] = {
6484 MockRead("HTTP/1.1 302 Redirect\r\n"),
6485 MockRead("Location: http://login.example.com/\r\n"),
6486 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066487 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296488 };
6489
6490 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6491 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066492 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296493
[email protected]bb88e1d32013-05-03 23:11:076494 session_deps_.socket_factory->AddSocketDataProvider(&data);
6495 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296496
[email protected]49639fa2011-12-20 23:22:416497 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296498
[email protected]3fe8d2f82013-10-17 08:56:076499 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296500 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416501 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296502
[email protected]49639fa2011-12-20 23:22:416503 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296504 EXPECT_EQ(ERR_IO_PENDING, rv);
6505
6506 rv = callback.WaitForResult();
6507 EXPECT_EQ(OK, rv);
6508 const HttpResponseInfo* response = trans->GetResponseInfo();
6509
[email protected]fe2255a2011-09-20 19:37:506510 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296511
6512 EXPECT_EQ(302, response->headers->response_code());
6513 std::string url;
6514 EXPECT_TRUE(response->headers->IsRedirect(&url));
6515 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206516
6517 // In the case of redirects from proxies, HttpNetworkTransaction returns
6518 // timing for the proxy connection instead of the connection to the host,
6519 // and no send / receive times.
6520 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6521 LoadTimingInfo load_timing_info;
6522 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6523
6524 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:296525 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:206526
6527 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6528 EXPECT_LE(load_timing_info.proxy_resolve_start,
6529 load_timing_info.proxy_resolve_end);
6530 EXPECT_LE(load_timing_info.proxy_resolve_end,
6531 load_timing_info.connect_timing.connect_start);
6532 ExpectConnectTimingHasTimes(
6533 load_timing_info.connect_timing,
6534 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6535
6536 EXPECT_TRUE(load_timing_info.send_start.is_null());
6537 EXPECT_TRUE(load_timing_info.send_end.is_null());
6538 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296539}
6540
6541// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026542TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076543 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296544 ProxyService::CreateFixed("https://proxy:70"));
6545
6546 HttpRequestInfo request;
6547 request.method = "GET";
bncce36dca22015-04-21 22:11:236548 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296549 request.load_flags = 0;
6550
lgarrona91df87f2014-12-05 00:51:346551 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236552 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206553 scoped_ptr<SpdyFrame> goaway(
6554 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296555 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136556 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6557 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296558 };
6559
6560 static const char* const kExtraHeaders[] = {
6561 "location",
6562 "http://login.example.com/",
6563 };
[email protected]ff98d7f02012-03-22 21:44:196564 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026565 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296566 arraysize(kExtraHeaders)/2, 1));
6567 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136568 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:296569 };
6570
rch8e6c6c42015-05-01 14:05:136571 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6572 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066573 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026574 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296575
[email protected]bb88e1d32013-05-03 23:11:076576 session_deps_.socket_factory->AddSocketDataProvider(&data);
6577 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296578
[email protected]49639fa2011-12-20 23:22:416579 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296580
[email protected]3fe8d2f82013-10-17 08:56:076581 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296582 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416583 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296584
[email protected]49639fa2011-12-20 23:22:416585 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296586 EXPECT_EQ(ERR_IO_PENDING, rv);
6587
6588 rv = callback.WaitForResult();
6589 EXPECT_EQ(OK, rv);
6590 const HttpResponseInfo* response = trans->GetResponseInfo();
6591
[email protected]fe2255a2011-09-20 19:37:506592 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296593
6594 EXPECT_EQ(302, response->headers->response_code());
6595 std::string url;
6596 EXPECT_TRUE(response->headers->IsRedirect(&url));
6597 EXPECT_EQ("http://login.example.com/", url);
6598}
6599
[email protected]4eddbc732012-08-09 05:40:176600// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026601TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176602 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076603 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296604 ProxyService::CreateFixed("https://proxy:70"));
6605
6606 HttpRequestInfo request;
6607 request.method = "GET";
bncce36dca22015-04-21 22:11:236608 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296609 request.load_flags = 0;
6610
6611 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236612 MockWrite(
6613 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6614 "Host: www.example.org\r\n"
6615 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296616 };
6617
6618 MockRead data_reads[] = {
6619 MockRead("HTTP/1.1 404 Not Found\r\n"),
6620 MockRead("Content-Length: 23\r\n\r\n"),
6621 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066622 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296623 };
6624
6625 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6626 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066627 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296628
[email protected]bb88e1d32013-05-03 23:11:076629 session_deps_.socket_factory->AddSocketDataProvider(&data);
6630 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296631
[email protected]49639fa2011-12-20 23:22:416632 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296633
[email protected]3fe8d2f82013-10-17 08:56:076634 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296635 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416636 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296637
[email protected]49639fa2011-12-20 23:22:416638 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296639 EXPECT_EQ(ERR_IO_PENDING, rv);
6640
6641 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176642 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296643
[email protected]4eddbc732012-08-09 05:40:176644 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296645}
6646
[email protected]4eddbc732012-08-09 05:40:176647// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026648TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176649 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076650 session_deps_.proxy_service.reset(
6651 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296652
6653 HttpRequestInfo request;
6654 request.method = "GET";
bncce36dca22015-04-21 22:11:236655 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296656 request.load_flags = 0;
6657
lgarrona91df87f2014-12-05 00:51:346658 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236659 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206660 scoped_ptr<SpdyFrame> rst(
6661 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296662 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136663 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:296664 };
6665
6666 static const char* const kExtraHeaders[] = {
6667 "location",
6668 "http://login.example.com/",
6669 };
[email protected]ff98d7f02012-03-22 21:44:196670 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026671 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296672 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196673 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026674 spdy_util_.ConstructSpdyBodyFrame(
6675 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296676 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136677 CreateMockRead(*resp.get(), 1),
6678 CreateMockRead(*body.get(), 2),
6679 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296680 };
6681
rch8e6c6c42015-05-01 14:05:136682 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6683 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066684 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026685 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296686
[email protected]bb88e1d32013-05-03 23:11:076687 session_deps_.socket_factory->AddSocketDataProvider(&data);
6688 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296689
[email protected]49639fa2011-12-20 23:22:416690 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296691
[email protected]3fe8d2f82013-10-17 08:56:076692 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296693 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416694 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296695
[email protected]49639fa2011-12-20 23:22:416696 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296697 EXPECT_EQ(ERR_IO_PENDING, rv);
6698
6699 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176700 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296701
[email protected]4eddbc732012-08-09 05:40:176702 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296703}
6704
[email protected]0c5fb722012-02-28 11:50:356705// Test the request-challenge-retry sequence for basic auth, through
6706// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026707TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356708 HttpRequestInfo request;
6709 request.method = "GET";
bncce36dca22015-04-21 22:11:236710 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:356711 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296712 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:356713
6714 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076715 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206716 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516717 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076718 session_deps_.net_log = log.bound().net_log();
6719 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356720
6721 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346722 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236723 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206724 scoped_ptr<SpdyFrame> rst(
6725 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356726
6727 // After calling trans->RestartWithAuth(), this is the request we should
6728 // be issuing -- the final header line contains the credentials.
6729 const char* const kAuthCredentials[] = {
6730 "proxy-authorization", "Basic Zm9vOmJhcg==",
6731 };
[email protected]fba2dbde2013-05-24 16:09:016732 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346733 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:236734 HostPortPair("www.example.org", 443)));
6735 // fetch https://www.example.org/ via HTTP
6736 const char get[] =
6737 "GET / HTTP/1.1\r\n"
6738 "Host: www.example.org\r\n"
6739 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196740 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026741 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356742
6743 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136744 CreateMockWrite(*req, 0, ASYNC),
6745 CreateMockWrite(*rst, 2, ASYNC),
6746 CreateMockWrite(*connect2, 3),
6747 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:356748 };
6749
6750 // The proxy responds to the connect with a 407, using a persistent
6751 // connection.
thestig9d3bb0c2015-01-24 00:49:516752 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356753 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356754 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6755 };
[email protected]745aa9c2014-06-27 02:21:296756 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6757 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356758
[email protected]23e482282013-06-14 16:08:026759 scoped_ptr<SpdyFrame> conn_resp(
6760 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356761 const char resp[] = "HTTP/1.1 200 OK\r\n"
6762 "Content-Length: 5\r\n\r\n";
6763
[email protected]ff98d7f02012-03-22 21:44:196764 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026765 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196766 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026767 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356768 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136769 CreateMockRead(*conn_auth_resp, 1, ASYNC),
6770 CreateMockRead(*conn_resp, 4, ASYNC),
6771 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
6772 CreateMockRead(*wrapped_body, 7, ASYNC),
6773 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356774 };
6775
rch8e6c6c42015-05-01 14:05:136776 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6777 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076778 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356779 // Negotiate SPDY to the proxy
6780 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026781 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076782 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356783 // Vanilla SSL to the server
6784 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076785 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356786
6787 TestCompletionCallback callback1;
6788
[email protected]262eec82013-03-19 21:01:366789 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506790 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356791
6792 int rv = trans->Start(&request, callback1.callback(), log.bound());
6793 EXPECT_EQ(ERR_IO_PENDING, rv);
6794
6795 rv = callback1.WaitForResult();
6796 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:466797 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:356798 log.GetEntries(&entries);
6799 size_t pos = ExpectLogContainsSomewhere(
6800 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6801 NetLog::PHASE_NONE);
6802 ExpectLogContainsSomewhere(
6803 entries, pos,
6804 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6805 NetLog::PHASE_NONE);
6806
6807 const HttpResponseInfo* response = trans->GetResponseInfo();
6808 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506809 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356810 EXPECT_EQ(407, response->headers->response_code());
6811 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6812 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6813 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6814
6815 TestCompletionCallback callback2;
6816
6817 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6818 callback2.callback());
6819 EXPECT_EQ(ERR_IO_PENDING, rv);
6820
6821 rv = callback2.WaitForResult();
6822 EXPECT_EQ(OK, rv);
6823
6824 response = trans->GetResponseInfo();
6825 ASSERT_TRUE(response != NULL);
6826
6827 EXPECT_TRUE(response->headers->IsKeepAlive());
6828 EXPECT_EQ(200, response->headers->response_code());
6829 EXPECT_EQ(5, response->headers->GetContentLength());
6830 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6831
6832 // The password prompt info should not be set.
6833 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6834
[email protected]029c83b62013-01-24 05:28:206835 LoadTimingInfo load_timing_info;
6836 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6837 TestLoadTimingNotReusedWithPac(load_timing_info,
6838 CONNECT_TIMING_HAS_SSL_TIMES);
6839
[email protected]0c5fb722012-02-28 11:50:356840 trans.reset();
6841 session->CloseAllConnections();
6842}
6843
[email protected]7c6f7ba2012-04-03 04:09:296844// Test that an explicitly trusted SPDY proxy can push a resource from an
6845// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026846TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296847 HttpRequestInfo request;
6848 HttpRequestInfo push_request;
6849
[email protected]7c6f7ba2012-04-03 04:09:296850 request.method = "GET";
bncce36dca22015-04-21 22:11:236851 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:296852 push_request.method = "GET";
6853 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6854
[email protected]7c6f7ba2012-04-03 04:09:296855 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076856 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206857 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516858 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076859 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506860
6861 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076862 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506863
[email protected]bb88e1d32013-05-03 23:11:076864 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296865
[email protected]cdf8f7e72013-05-23 10:56:466866 scoped_ptr<SpdyFrame> stream1_syn(
6867 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296868
6869 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136870 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296871 };
6872
6873 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026874 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296875
6876 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026877 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296878
6879 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026880 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296881 0,
6882 2,
6883 1,
6884 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436885 const char kPushedData[] = "pushed";
6886 scoped_ptr<SpdyFrame> stream2_body(
6887 spdy_util_.ConstructSpdyBodyFrame(
6888 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296889
6890 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136891 CreateMockRead(*stream1_reply, 1, ASYNC),
6892 CreateMockRead(*stream2_syn, 2, ASYNC),
6893 CreateMockRead(*stream1_body, 3, ASYNC),
6894 CreateMockRead(*stream2_body, 4, ASYNC),
6895 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:296896 };
6897
rch8e6c6c42015-05-01 14:05:136898 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6899 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076900 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296901 // Negotiate SPDY to the proxy
6902 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026903 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076904 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296905
[email protected]262eec82013-03-19 21:01:366906 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506907 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296908 TestCompletionCallback callback;
6909 int rv = trans->Start(&request, callback.callback(), log.bound());
6910 EXPECT_EQ(ERR_IO_PENDING, rv);
6911
6912 rv = callback.WaitForResult();
6913 EXPECT_EQ(OK, rv);
6914 const HttpResponseInfo* response = trans->GetResponseInfo();
6915
[email protected]262eec82013-03-19 21:01:366916 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506917 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6918 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296919 EXPECT_EQ(ERR_IO_PENDING, rv);
6920
6921 rv = callback.WaitForResult();
6922 EXPECT_EQ(OK, rv);
6923 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6924
6925 ASSERT_TRUE(response != NULL);
6926 EXPECT_TRUE(response->headers->IsKeepAlive());
6927
6928 EXPECT_EQ(200, response->headers->response_code());
6929 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6930
6931 std::string response_data;
6932 rv = ReadTransaction(trans.get(), &response_data);
6933 EXPECT_EQ(OK, rv);
6934 EXPECT_EQ("hello!", response_data);
6935
[email protected]029c83b62013-01-24 05:28:206936 LoadTimingInfo load_timing_info;
6937 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6938 TestLoadTimingNotReusedWithPac(load_timing_info,
6939 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6940
[email protected]7c6f7ba2012-04-03 04:09:296941 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506942 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296943 EXPECT_EQ(200, push_response->headers->response_code());
6944
6945 rv = ReadTransaction(push_trans.get(), &response_data);
6946 EXPECT_EQ(OK, rv);
6947 EXPECT_EQ("pushed", response_data);
6948
[email protected]029c83b62013-01-24 05:28:206949 LoadTimingInfo push_load_timing_info;
6950 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6951 TestLoadTimingReusedWithPac(push_load_timing_info);
6952 // The transactions should share a socket ID, despite being for different
6953 // origins.
6954 EXPECT_EQ(load_timing_info.socket_log_id,
6955 push_load_timing_info.socket_log_id);
6956
[email protected]7c6f7ba2012-04-03 04:09:296957 trans.reset();
6958 push_trans.reset();
6959 session->CloseAllConnections();
6960}
6961
[email protected]8c843192012-04-05 07:15:006962// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026963TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006964 HttpRequestInfo request;
6965
6966 request.method = "GET";
bncce36dca22015-04-21 22:11:236967 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:006968
[email protected]8c843192012-04-05 07:15:006969 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076970 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006971 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516972 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076973 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506974
6975 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076976 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506977
[email protected]bb88e1d32013-05-03 23:11:076978 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006979
[email protected]cdf8f7e72013-05-23 10:56:466980 scoped_ptr<SpdyFrame> stream1_syn(
6981 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006982
6983 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206984 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006985
6986 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136987 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:006988 };
6989
6990 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026991 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006992
6993 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026994 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006995
6996 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026997 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006998 0,
6999 2,
7000 1,
7001 "https://www.another-origin.com/foo.dat"));
7002
7003 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137004 CreateMockRead(*stream1_reply, 1, ASYNC),
7005 CreateMockRead(*stream2_syn, 2, ASYNC),
7006 CreateMockRead(*stream1_body, 4, ASYNC),
7007 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007008 };
7009
rch8e6c6c42015-05-01 14:05:137010 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7011 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077012 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007013 // Negotiate SPDY to the proxy
7014 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027015 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077016 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007017
[email protected]262eec82013-03-19 21:01:367018 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507019 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007020 TestCompletionCallback callback;
7021 int rv = trans->Start(&request, callback.callback(), log.bound());
7022 EXPECT_EQ(ERR_IO_PENDING, rv);
7023
7024 rv = callback.WaitForResult();
7025 EXPECT_EQ(OK, rv);
7026 const HttpResponseInfo* response = trans->GetResponseInfo();
7027
7028 ASSERT_TRUE(response != NULL);
7029 EXPECT_TRUE(response->headers->IsKeepAlive());
7030
7031 EXPECT_EQ(200, response->headers->response_code());
7032 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7033
7034 std::string response_data;
7035 rv = ReadTransaction(trans.get(), &response_data);
7036 EXPECT_EQ(OK, rv);
7037 EXPECT_EQ("hello!", response_data);
7038
7039 trans.reset();
7040 session->CloseAllConnections();
7041}
7042
[email protected]2df19bb2010-08-25 20:13:467043// Test HTTPS connections to a site with a bad certificate, going through an
7044// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027045TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:077046 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:117047 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:467048
7049 HttpRequestInfo request;
7050 request.method = "GET";
bncce36dca22015-04-21 22:11:237051 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467052 request.load_flags = 0;
7053
7054 // Attempt to fetch the URL from a server with a bad cert
7055 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237056 MockWrite(
7057 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7058 "Host: www.example.org\r\n"
7059 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467060 };
7061
7062 MockRead bad_cert_reads[] = {
7063 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067064 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467065 };
7066
7067 // Attempt to fetch the URL with a good cert
7068 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237069 MockWrite(
7070 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7071 "Host: www.example.org\r\n"
7072 "Proxy-Connection: keep-alive\r\n\r\n"),
7073 MockWrite(
7074 "GET / HTTP/1.1\r\n"
7075 "Host: www.example.org\r\n"
7076 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467077 };
7078
7079 MockRead good_cert_reads[] = {
7080 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7081 MockRead("HTTP/1.0 200 OK\r\n"),
7082 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7083 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067084 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467085 };
7086
7087 StaticSocketDataProvider ssl_bad_certificate(
7088 bad_cert_reads, arraysize(bad_cert_reads),
7089 bad_cert_writes, arraysize(bad_cert_writes));
7090 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7091 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067092 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7093 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467094
7095 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077096 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7097 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7098 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467099
7100 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077101 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7102 session_deps_.socket_factory->AddSocketDataProvider(&data);
7103 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467104
[email protected]49639fa2011-12-20 23:22:417105 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467106
[email protected]3fe8d2f82013-10-17 08:56:077107 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467108 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417109 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467110
[email protected]49639fa2011-12-20 23:22:417111 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467112 EXPECT_EQ(ERR_IO_PENDING, rv);
7113
7114 rv = callback.WaitForResult();
7115 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7116
[email protected]49639fa2011-12-20 23:22:417117 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467118 EXPECT_EQ(ERR_IO_PENDING, rv);
7119
7120 rv = callback.WaitForResult();
7121 EXPECT_EQ(OK, rv);
7122
7123 const HttpResponseInfo* response = trans->GetResponseInfo();
7124
[email protected]fe2255a2011-09-20 19:37:507125 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467126 EXPECT_EQ(100, response->headers->GetContentLength());
7127}
7128
[email protected]23e482282013-06-14 16:08:027129TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427130 HttpRequestInfo request;
7131 request.method = "GET";
bncce36dca22015-04-21 22:11:237132 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437133 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7134 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427135
[email protected]3fe8d2f82013-10-17 08:56:077136 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277137 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417138 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277139
[email protected]1c773ea12009-04-28 19:58:427140 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237141 MockWrite(
7142 "GET / HTTP/1.1\r\n"
7143 "Host: www.example.org\r\n"
7144 "Connection: keep-alive\r\n"
7145 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427146 };
7147
7148 // Lastly, the server responds with the actual content.
7149 MockRead data_reads[] = {
7150 MockRead("HTTP/1.0 200 OK\r\n"),
7151 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7152 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067153 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427154 };
7155
[email protected]31a2bfe2010-02-09 08:03:397156 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7157 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077158 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427159
[email protected]49639fa2011-12-20 23:22:417160 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427161
[email protected]49639fa2011-12-20 23:22:417162 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427163 EXPECT_EQ(ERR_IO_PENDING, rv);
7164
7165 rv = callback.WaitForResult();
7166 EXPECT_EQ(OK, rv);
7167}
7168
[email protected]23e482282013-06-14 16:08:027169TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297170 HttpRequestInfo request;
7171 request.method = "GET";
bncce36dca22015-04-21 22:11:237172 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297173 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7174 "Chromium Ultra Awesome X Edition");
7175
[email protected]bb88e1d32013-05-03 23:11:077176 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:077177 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277178 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417179 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277180
[email protected]da81f132010-08-18 23:39:297181 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237182 MockWrite(
7183 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7184 "Host: www.example.org\r\n"
7185 "Proxy-Connection: keep-alive\r\n"
7186 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297187 };
7188 MockRead data_reads[] = {
7189 // Return an error, so the transaction stops here (this test isn't
7190 // interested in the rest).
7191 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7192 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7193 MockRead("Proxy-Connection: close\r\n\r\n"),
7194 };
7195
7196 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7197 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077198 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297199
[email protected]49639fa2011-12-20 23:22:417200 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297201
[email protected]49639fa2011-12-20 23:22:417202 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297203 EXPECT_EQ(ERR_IO_PENDING, rv);
7204
7205 rv = callback.WaitForResult();
7206 EXPECT_EQ(OK, rv);
7207}
7208
[email protected]23e482282013-06-14 16:08:027209TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427210 HttpRequestInfo request;
7211 request.method = "GET";
bncce36dca22015-04-21 22:11:237212 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427213 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167214 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7215 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427216
[email protected]3fe8d2f82013-10-17 08:56:077217 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277218 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417219 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277220
[email protected]1c773ea12009-04-28 19:58:427221 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237222 MockWrite(
7223 "GET / HTTP/1.1\r\n"
7224 "Host: www.example.org\r\n"
7225 "Connection: keep-alive\r\n"
7226 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427227 };
7228
7229 // Lastly, the server responds with the actual content.
7230 MockRead data_reads[] = {
7231 MockRead("HTTP/1.0 200 OK\r\n"),
7232 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7233 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067234 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427235 };
7236
[email protected]31a2bfe2010-02-09 08:03:397237 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7238 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077239 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427240
[email protected]49639fa2011-12-20 23:22:417241 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427242
[email protected]49639fa2011-12-20 23:22:417243 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427244 EXPECT_EQ(ERR_IO_PENDING, rv);
7245
7246 rv = callback.WaitForResult();
7247 EXPECT_EQ(OK, rv);
7248}
7249
[email protected]23e482282013-06-14 16:08:027250TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427251 HttpRequestInfo request;
7252 request.method = "POST";
bncce36dca22015-04-21 22:11:237253 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427254
[email protected]3fe8d2f82013-10-17 08:56:077255 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277256 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417257 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277258
[email protected]1c773ea12009-04-28 19:58:427259 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237260 MockWrite(
7261 "POST / HTTP/1.1\r\n"
7262 "Host: www.example.org\r\n"
7263 "Connection: keep-alive\r\n"
7264 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427265 };
7266
7267 // Lastly, the server responds with the actual content.
7268 MockRead data_reads[] = {
7269 MockRead("HTTP/1.0 200 OK\r\n"),
7270 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7271 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067272 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427273 };
7274
[email protected]31a2bfe2010-02-09 08:03:397275 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7276 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077277 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427278
[email protected]49639fa2011-12-20 23:22:417279 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427280
[email protected]49639fa2011-12-20 23:22:417281 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427282 EXPECT_EQ(ERR_IO_PENDING, rv);
7283
7284 rv = callback.WaitForResult();
7285 EXPECT_EQ(OK, rv);
7286}
7287
[email protected]23e482282013-06-14 16:08:027288TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427289 HttpRequestInfo request;
7290 request.method = "PUT";
bncce36dca22015-04-21 22:11:237291 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427292
[email protected]3fe8d2f82013-10-17 08:56:077293 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277294 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277296
[email protected]1c773ea12009-04-28 19:58:427297 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237298 MockWrite(
7299 "PUT / HTTP/1.1\r\n"
7300 "Host: www.example.org\r\n"
7301 "Connection: keep-alive\r\n"
7302 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427303 };
7304
7305 // Lastly, the server responds with the actual content.
7306 MockRead data_reads[] = {
7307 MockRead("HTTP/1.0 200 OK\r\n"),
7308 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7309 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067310 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427311 };
7312
[email protected]31a2bfe2010-02-09 08:03:397313 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7314 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077315 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427316
[email protected]49639fa2011-12-20 23:22:417317 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427318
[email protected]49639fa2011-12-20 23:22:417319 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427320 EXPECT_EQ(ERR_IO_PENDING, rv);
7321
7322 rv = callback.WaitForResult();
7323 EXPECT_EQ(OK, rv);
7324}
7325
[email protected]23e482282013-06-14 16:08:027326TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427327 HttpRequestInfo request;
7328 request.method = "HEAD";
bncce36dca22015-04-21 22:11:237329 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427330
[email protected]3fe8d2f82013-10-17 08:56:077331 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277332 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277334
[email protected]1c773ea12009-04-28 19:58:427335 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:137336 MockWrite("HEAD / HTTP/1.1\r\n"
7337 "Host: www.example.org\r\n"
7338 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427339 };
7340
7341 // Lastly, the server responds with the actual content.
7342 MockRead data_reads[] = {
7343 MockRead("HTTP/1.0 200 OK\r\n"),
7344 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7345 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067346 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427347 };
7348
[email protected]31a2bfe2010-02-09 08:03:397349 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7350 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077351 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427352
[email protected]49639fa2011-12-20 23:22:417353 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427354
[email protected]49639fa2011-12-20 23:22:417355 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427356 EXPECT_EQ(ERR_IO_PENDING, rv);
7357
7358 rv = callback.WaitForResult();
7359 EXPECT_EQ(OK, rv);
7360}
7361
[email protected]23e482282013-06-14 16:08:027362TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427363 HttpRequestInfo request;
7364 request.method = "GET";
bncce36dca22015-04-21 22:11:237365 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427366 request.load_flags = LOAD_BYPASS_CACHE;
7367
[email protected]3fe8d2f82013-10-17 08:56:077368 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277369 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417370 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277371
[email protected]1c773ea12009-04-28 19:58:427372 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237373 MockWrite(
7374 "GET / HTTP/1.1\r\n"
7375 "Host: www.example.org\r\n"
7376 "Connection: keep-alive\r\n"
7377 "Pragma: no-cache\r\n"
7378 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427379 };
7380
7381 // Lastly, the server responds with the actual content.
7382 MockRead data_reads[] = {
7383 MockRead("HTTP/1.0 200 OK\r\n"),
7384 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7385 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067386 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427387 };
7388
[email protected]31a2bfe2010-02-09 08:03:397389 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7390 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077391 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427392
[email protected]49639fa2011-12-20 23:22:417393 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427394
[email protected]49639fa2011-12-20 23:22:417395 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427396 EXPECT_EQ(ERR_IO_PENDING, rv);
7397
7398 rv = callback.WaitForResult();
7399 EXPECT_EQ(OK, rv);
7400}
7401
[email protected]23e482282013-06-14 16:08:027402TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427403 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427404 HttpRequestInfo request;
7405 request.method = "GET";
bncce36dca22015-04-21 22:11:237406 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427407 request.load_flags = LOAD_VALIDATE_CACHE;
7408
[email protected]3fe8d2f82013-10-17 08:56:077409 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277410 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417411 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277412
[email protected]1c773ea12009-04-28 19:58:427413 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237414 MockWrite(
7415 "GET / HTTP/1.1\r\n"
7416 "Host: www.example.org\r\n"
7417 "Connection: keep-alive\r\n"
7418 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427419 };
7420
7421 // Lastly, the server responds with the actual content.
7422 MockRead data_reads[] = {
7423 MockRead("HTTP/1.0 200 OK\r\n"),
7424 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7425 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067426 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427427 };
7428
[email protected]31a2bfe2010-02-09 08:03:397429 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7430 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077431 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427432
[email protected]49639fa2011-12-20 23:22:417433 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427434
[email protected]49639fa2011-12-20 23:22:417435 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427436 EXPECT_EQ(ERR_IO_PENDING, rv);
7437
7438 rv = callback.WaitForResult();
7439 EXPECT_EQ(OK, rv);
7440}
7441
[email protected]23e482282013-06-14 16:08:027442TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427443 HttpRequestInfo request;
7444 request.method = "GET";
bncce36dca22015-04-21 22:11:237445 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437446 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427447
[email protected]3fe8d2f82013-10-17 08:56:077448 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277449 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417450 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277451
[email protected]1c773ea12009-04-28 19:58:427452 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237453 MockWrite(
7454 "GET / HTTP/1.1\r\n"
7455 "Host: www.example.org\r\n"
7456 "Connection: keep-alive\r\n"
7457 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427458 };
7459
7460 // Lastly, the server responds with the actual content.
7461 MockRead data_reads[] = {
7462 MockRead("HTTP/1.0 200 OK\r\n"),
7463 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7464 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067465 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427466 };
7467
[email protected]31a2bfe2010-02-09 08:03:397468 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7469 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077470 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427471
[email protected]49639fa2011-12-20 23:22:417472 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427473
[email protected]49639fa2011-12-20 23:22:417474 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427475 EXPECT_EQ(ERR_IO_PENDING, rv);
7476
7477 rv = callback.WaitForResult();
7478 EXPECT_EQ(OK, rv);
7479}
7480
[email protected]23e482282013-06-14 16:08:027481TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477482 HttpRequestInfo request;
7483 request.method = "GET";
bncce36dca22015-04-21 22:11:237484 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437485 request.extra_headers.SetHeader("referer", "www.foo.com");
7486 request.extra_headers.SetHeader("hEllo", "Kitty");
7487 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477488
[email protected]3fe8d2f82013-10-17 08:56:077489 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277490 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417491 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277492
[email protected]270c6412010-03-29 22:02:477493 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237494 MockWrite(
7495 "GET / HTTP/1.1\r\n"
7496 "Host: www.example.org\r\n"
7497 "Connection: keep-alive\r\n"
7498 "referer: www.foo.com\r\n"
7499 "hEllo: Kitty\r\n"
7500 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:477501 };
7502
7503 // Lastly, the server responds with the actual content.
7504 MockRead data_reads[] = {
7505 MockRead("HTTP/1.0 200 OK\r\n"),
7506 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7507 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067508 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477509 };
7510
7511 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7512 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077513 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477514
[email protected]49639fa2011-12-20 23:22:417515 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477516
[email protected]49639fa2011-12-20 23:22:417517 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477518 EXPECT_EQ(ERR_IO_PENDING, rv);
7519
7520 rv = callback.WaitForResult();
7521 EXPECT_EQ(OK, rv);
7522}
7523
[email protected]23e482282013-06-14 16:08:027524TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277525 HttpRequestInfo request;
7526 request.method = "GET";
bncce36dca22015-04-21 22:11:237527 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277528 request.load_flags = 0;
7529
[email protected]bb88e1d32013-05-03 23:11:077530 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207531 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517532 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077533 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027534
[email protected]3fe8d2f82013-10-17 08:56:077535 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027536 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417537 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027538
[email protected]3cd17242009-06-23 02:59:027539 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7540 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7541
7542 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237543 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7544 MockWrite(
7545 "GET / HTTP/1.1\r\n"
7546 "Host: www.example.org\r\n"
7547 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027548
7549 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067550 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027551 MockRead("HTTP/1.0 200 OK\r\n"),
7552 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7553 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067554 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027555 };
7556
[email protected]31a2bfe2010-02-09 08:03:397557 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7558 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077559 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027560
[email protected]49639fa2011-12-20 23:22:417561 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027562
[email protected]49639fa2011-12-20 23:22:417563 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027564 EXPECT_EQ(ERR_IO_PENDING, rv);
7565
7566 rv = callback.WaitForResult();
7567 EXPECT_EQ(OK, rv);
7568
7569 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507570 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027571
[email protected]029c83b62013-01-24 05:28:207572 LoadTimingInfo load_timing_info;
7573 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7574 TestLoadTimingNotReusedWithPac(load_timing_info,
7575 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7576
[email protected]3cd17242009-06-23 02:59:027577 std::string response_text;
7578 rv = ReadTransaction(trans.get(), &response_text);
7579 EXPECT_EQ(OK, rv);
7580 EXPECT_EQ("Payload", response_text);
7581}
7582
[email protected]23e482282013-06-14 16:08:027583TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277584 HttpRequestInfo request;
7585 request.method = "GET";
bncce36dca22015-04-21 22:11:237586 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277587 request.load_flags = 0;
7588
[email protected]bb88e1d32013-05-03 23:11:077589 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207590 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517591 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077592 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027593
[email protected]3fe8d2f82013-10-17 08:56:077594 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027595 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417596 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027597
[email protected]3cd17242009-06-23 02:59:027598 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7599 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7600
7601 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237602 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7603 arraysize(write_buffer)),
7604 MockWrite(
7605 "GET / HTTP/1.1\r\n"
7606 "Host: www.example.org\r\n"
7607 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027608
7609 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017610 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7611 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357612 MockRead("HTTP/1.0 200 OK\r\n"),
7613 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7614 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067615 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357616 };
7617
[email protected]31a2bfe2010-02-09 08:03:397618 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7619 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077620 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357621
[email protected]8ddf8322012-02-23 18:08:067622 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357624
[email protected]49639fa2011-12-20 23:22:417625 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357626
[email protected]49639fa2011-12-20 23:22:417627 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357628 EXPECT_EQ(ERR_IO_PENDING, rv);
7629
7630 rv = callback.WaitForResult();
7631 EXPECT_EQ(OK, rv);
7632
[email protected]029c83b62013-01-24 05:28:207633 LoadTimingInfo load_timing_info;
7634 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7635 TestLoadTimingNotReusedWithPac(load_timing_info,
7636 CONNECT_TIMING_HAS_SSL_TIMES);
7637
[email protected]e0c27be2009-07-15 13:09:357638 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507639 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357640
7641 std::string response_text;
7642 rv = ReadTransaction(trans.get(), &response_text);
7643 EXPECT_EQ(OK, rv);
7644 EXPECT_EQ("Payload", response_text);
7645}
7646
[email protected]23e482282013-06-14 16:08:027647TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207648 HttpRequestInfo request;
7649 request.method = "GET";
bncce36dca22015-04-21 22:11:237650 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:207651 request.load_flags = 0;
7652
[email protected]bb88e1d32013-05-03 23:11:077653 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207654 ProxyService::CreateFixed("socks4://myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517655 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077656 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207657
[email protected]3fe8d2f82013-10-17 08:56:077658 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207659 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417660 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207661
7662 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7663 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7664
7665 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237666 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7667 MockWrite(
7668 "GET / HTTP/1.1\r\n"
7669 "Host: www.example.org\r\n"
7670 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:207671
7672 MockRead data_reads[] = {
7673 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7674 MockRead("HTTP/1.0 200 OK\r\n"),
7675 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7676 MockRead("Payload"),
7677 MockRead(SYNCHRONOUS, OK)
7678 };
7679
7680 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7681 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077682 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207683
7684 TestCompletionCallback callback;
7685
7686 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7687 EXPECT_EQ(ERR_IO_PENDING, rv);
7688
7689 rv = callback.WaitForResult();
7690 EXPECT_EQ(OK, rv);
7691
7692 const HttpResponseInfo* response = trans->GetResponseInfo();
7693 ASSERT_TRUE(response != NULL);
7694
7695 LoadTimingInfo load_timing_info;
7696 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7697 TestLoadTimingNotReused(load_timing_info,
7698 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7699
7700 std::string response_text;
7701 rv = ReadTransaction(trans.get(), &response_text);
7702 EXPECT_EQ(OK, rv);
7703 EXPECT_EQ("Payload", response_text);
7704}
7705
[email protected]23e482282013-06-14 16:08:027706TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277707 HttpRequestInfo request;
7708 request.method = "GET";
bncce36dca22015-04-21 22:11:237709 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277710 request.load_flags = 0;
7711
[email protected]bb88e1d32013-05-03 23:11:077712 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207713 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517714 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077715 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357716
[email protected]3fe8d2f82013-10-17 08:56:077717 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357718 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417719 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357720
[email protected]e0c27be2009-07-15 13:09:357721 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7722 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377723 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237724 0x05, // Version
7725 0x01, // Command (CONNECT)
7726 0x00, // Reserved.
7727 0x03, // Address type (DOMAINNAME).
7728 0x0F, // Length of domain (15)
7729 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7730 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:377731 };
[email protected]e0c27be2009-07-15 13:09:357732 const char kSOCKS5OkResponse[] =
7733 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7734
7735 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237736 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7737 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7738 MockWrite(
7739 "GET / HTTP/1.1\r\n"
7740 "Host: www.example.org\r\n"
7741 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357742
7743 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017744 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7745 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357746 MockRead("HTTP/1.0 200 OK\r\n"),
7747 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7748 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067749 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357750 };
7751
[email protected]31a2bfe2010-02-09 08:03:397752 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7753 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077754 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357755
[email protected]49639fa2011-12-20 23:22:417756 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357757
[email protected]49639fa2011-12-20 23:22:417758 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357759 EXPECT_EQ(ERR_IO_PENDING, rv);
7760
7761 rv = callback.WaitForResult();
7762 EXPECT_EQ(OK, rv);
7763
7764 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507765 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357766
[email protected]029c83b62013-01-24 05:28:207767 LoadTimingInfo load_timing_info;
7768 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7769 TestLoadTimingNotReusedWithPac(load_timing_info,
7770 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7771
[email protected]e0c27be2009-07-15 13:09:357772 std::string response_text;
7773 rv = ReadTransaction(trans.get(), &response_text);
7774 EXPECT_EQ(OK, rv);
7775 EXPECT_EQ("Payload", response_text);
7776}
7777
[email protected]23e482282013-06-14 16:08:027778TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277779 HttpRequestInfo request;
7780 request.method = "GET";
bncce36dca22015-04-21 22:11:237781 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277782 request.load_flags = 0;
7783
[email protected]bb88e1d32013-05-03 23:11:077784 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207785 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517786 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077787 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357788
[email protected]3fe8d2f82013-10-17 08:56:077789 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357790 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417791 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357792
[email protected]e0c27be2009-07-15 13:09:357793 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7794 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377795 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237796 0x05, // Version
7797 0x01, // Command (CONNECT)
7798 0x00, // Reserved.
7799 0x03, // Address type (DOMAINNAME).
7800 0x0F, // Length of domain (15)
7801 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7802 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:377803 };
7804
[email protected]e0c27be2009-07-15 13:09:357805 const char kSOCKS5OkResponse[] =
7806 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7807
7808 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237809 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7810 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7811 arraysize(kSOCKS5OkRequest)),
7812 MockWrite(
7813 "GET / HTTP/1.1\r\n"
7814 "Host: www.example.org\r\n"
7815 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357816
7817 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017818 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7819 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027820 MockRead("HTTP/1.0 200 OK\r\n"),
7821 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7822 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067823 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027824 };
7825
[email protected]31a2bfe2010-02-09 08:03:397826 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7827 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077828 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027829
[email protected]8ddf8322012-02-23 18:08:067830 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077831 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027832
[email protected]49639fa2011-12-20 23:22:417833 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027834
[email protected]49639fa2011-12-20 23:22:417835 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027836 EXPECT_EQ(ERR_IO_PENDING, rv);
7837
7838 rv = callback.WaitForResult();
7839 EXPECT_EQ(OK, rv);
7840
7841 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507842 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027843
[email protected]029c83b62013-01-24 05:28:207844 LoadTimingInfo load_timing_info;
7845 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7846 TestLoadTimingNotReusedWithPac(load_timing_info,
7847 CONNECT_TIMING_HAS_SSL_TIMES);
7848
[email protected]3cd17242009-06-23 02:59:027849 std::string response_text;
7850 rv = ReadTransaction(trans.get(), &response_text);
7851 EXPECT_EQ(OK, rv);
7852 EXPECT_EQ("Payload", response_text);
7853}
7854
[email protected]448d4ca52012-03-04 04:12:237855namespace {
7856
[email protected]04e5be32009-06-26 20:00:317857// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067858
7859struct GroupNameTest {
7860 std::string proxy_server;
7861 std::string url;
7862 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187863 bool ssl;
[email protected]2d731a32010-04-29 01:04:067864};
7865
7866scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437867 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077868 SpdySessionDependencies* session_deps_) {
7869 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067870
[email protected]30d4c022013-07-18 22:58:167871 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537872 session->http_server_properties();
bnccacc0992015-03-20 20:22:227873 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:257874 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:127875 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:227876 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:127877 HostPortPair("host.with.alternate", 80), alternative_service, 1.0,
7878 expiration);
[email protected]2d731a32010-04-29 01:04:067879
7880 return session;
7881}
7882
7883int GroupNameTransactionHelper(
7884 const std::string& url,
7885 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067886 HttpRequestInfo request;
7887 request.method = "GET";
7888 request.url = GURL(url);
7889 request.load_flags = 0;
7890
[email protected]262eec82013-03-19 21:01:367891 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507892 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277893
[email protected]49639fa2011-12-20 23:22:417894 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067895
7896 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417897 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067898}
7899
[email protected]448d4ca52012-03-04 04:12:237900} // namespace
7901
[email protected]23e482282013-06-14 16:08:027902TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067903 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237904 {
7905 "", // unused
7906 "http://www.example.org/direct",
7907 "www.example.org:80",
7908 false,
7909 },
7910 {
7911 "", // unused
7912 "http://[2001:1418:13:1::25]/direct",
7913 "[2001:1418:13:1::25]:80",
7914 false,
7915 },
[email protected]04e5be32009-06-26 20:00:317916
bncce36dca22015-04-21 22:11:237917 // SSL Tests
7918 {
7919 "", // unused
7920 "https://www.example.org/direct_ssl",
7921 "ssl/www.example.org:443",
7922 true,
7923 },
7924 {
7925 "", // unused
7926 "https://[2001:1418:13:1::25]/direct",
7927 "ssl/[2001:1418:13:1::25]:443",
7928 true,
7929 },
7930 {
7931 "", // unused
7932 "http://host.with.alternate/direct",
7933 "ssl/host.with.alternate:443",
7934 true,
7935 },
[email protected]2d731a32010-04-29 01:04:067936 };
[email protected]2ff8b312010-04-26 22:20:547937
[email protected]d7599122014-05-24 03:37:237938 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067939
viettrungluue4a8b882014-10-16 06:17:387940 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077941 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027942 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067943 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437944 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067945
7946 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287947 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7948 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137949 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347950 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447951 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7952 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027953 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7954 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517955 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067956
7957 EXPECT_EQ(ERR_IO_PENDING,
7958 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187959 if (tests[i].ssl)
7960 EXPECT_EQ(tests[i].expected_group_name,
7961 ssl_conn_pool->last_group_name_received());
7962 else
7963 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287964 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067965 }
[email protected]2d731a32010-04-29 01:04:067966}
7967
[email protected]23e482282013-06-14 16:08:027968TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067969 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237970 {
7971 "http_proxy",
7972 "http://www.example.org/http_proxy_normal",
7973 "www.example.org:80",
7974 false,
7975 },
[email protected]2d731a32010-04-29 01:04:067976
bncce36dca22015-04-21 22:11:237977 // SSL Tests
7978 {
7979 "http_proxy",
7980 "https://www.example.org/http_connect_ssl",
7981 "ssl/www.example.org:443",
7982 true,
7983 },
[email protected]af3490e2010-10-16 21:02:297984
bncce36dca22015-04-21 22:11:237985 {
7986 "http_proxy",
7987 "http://host.with.alternate/direct",
7988 "ssl/host.with.alternate:443",
7989 true,
7990 },
[email protected]45499252013-01-23 17:12:567991
bncce36dca22015-04-21 22:11:237992 {
7993 "http_proxy",
7994 "ftp://ftp.google.com/http_proxy_normal",
7995 "ftp/ftp.google.com:21",
7996 false,
7997 },
[email protected]2d731a32010-04-29 01:04:067998 };
7999
[email protected]d7599122014-05-24 03:37:238000 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:068001
viettrungluue4a8b882014-10-16 06:17:388002 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078003 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028004 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068005 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438006 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068007
8008 HttpNetworkSessionPeer peer(session);
8009
[email protected]e60e47a2010-07-14 03:37:188010 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138011 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348012 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138013 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348014 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028015
[email protected]831e4a32013-11-14 02:14:448016 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8017 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028018 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8019 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518020 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068021
8022 EXPECT_EQ(ERR_IO_PENDING,
8023 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188024 if (tests[i].ssl)
8025 EXPECT_EQ(tests[i].expected_group_name,
8026 ssl_conn_pool->last_group_name_received());
8027 else
8028 EXPECT_EQ(tests[i].expected_group_name,
8029 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068030 }
[email protected]2d731a32010-04-29 01:04:068031}
8032
[email protected]23e482282013-06-14 16:08:028033TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068034 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238035 {
8036 "socks4://socks_proxy:1080",
8037 "http://www.example.org/socks4_direct",
8038 "socks4/www.example.org:80",
8039 false,
8040 },
8041 {
8042 "socks5://socks_proxy:1080",
8043 "http://www.example.org/socks5_direct",
8044 "socks5/www.example.org:80",
8045 false,
8046 },
[email protected]2d731a32010-04-29 01:04:068047
bncce36dca22015-04-21 22:11:238048 // SSL Tests
8049 {
8050 "socks4://socks_proxy:1080",
8051 "https://www.example.org/socks4_ssl",
8052 "socks4/ssl/www.example.org:443",
8053 true,
8054 },
8055 {
8056 "socks5://socks_proxy:1080",
8057 "https://www.example.org/socks5_ssl",
8058 "socks5/ssl/www.example.org:443",
8059 true,
8060 },
[email protected]af3490e2010-10-16 21:02:298061
bncce36dca22015-04-21 22:11:238062 {
8063 "socks4://socks_proxy:1080",
8064 "http://host.with.alternate/direct",
8065 "socks4/ssl/host.with.alternate:443",
8066 true,
8067 },
[email protected]04e5be32009-06-26 20:00:318068 };
8069
[email protected]d7599122014-05-24 03:37:238070 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:548071
viettrungluue4a8b882014-10-16 06:17:388072 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078073 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028074 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068075 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438076 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028077
[email protected]2d731a32010-04-29 01:04:068078 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318079
[email protected]e60e47a2010-07-14 03:37:188080 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138081 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348082 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138083 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348084 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028085
[email protected]831e4a32013-11-14 02:14:448086 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8087 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028088 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8089 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518090 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318091
[email protected]262eec82013-03-19 21:01:368092 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508093 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318094
[email protected]2d731a32010-04-29 01:04:068095 EXPECT_EQ(ERR_IO_PENDING,
8096 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188097 if (tests[i].ssl)
8098 EXPECT_EQ(tests[i].expected_group_name,
8099 ssl_conn_pool->last_group_name_received());
8100 else
8101 EXPECT_EQ(tests[i].expected_group_name,
8102 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318103 }
8104}
8105
[email protected]23e482282013-06-14 16:08:028106TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278107 HttpRequestInfo request;
8108 request.method = "GET";
bncce36dca22015-04-21 22:11:238109 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278110
[email protected]bb88e1d32013-05-03 23:11:078111 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008112 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328113
[email protected]69719062010-01-05 20:09:218114 // This simulates failure resolving all hostnames; that means we will fail
8115 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078116 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328117
[email protected]3fe8d2f82013-10-17 08:56:078118 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258119 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258121
[email protected]49639fa2011-12-20 23:22:418122 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258123
[email protected]49639fa2011-12-20 23:22:418124 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258125 EXPECT_EQ(ERR_IO_PENDING, rv);
8126
[email protected]9172a982009-06-06 00:30:258127 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018128 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258129}
8130
[email protected]685af592010-05-11 19:31:248131// Base test to make sure that when the load flags for a request specify to
8132// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028133void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078134 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278135 // Issue a request, asking to bypass the cache(s).
8136 HttpRequestInfo request;
8137 request.method = "GET";
8138 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238139 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278140
[email protected]a2c2fb92009-07-18 07:31:048141 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078142 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328143
[email protected]3fe8d2f82013-10-17 08:56:078144 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8145 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418146 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288147
bncce36dca22015-04-21 22:11:238148 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288149 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298150 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078151 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238152 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8153 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478154 EXPECT_EQ(ERR_IO_PENDING, rv);
8155 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288156 EXPECT_EQ(OK, rv);
8157
8158 // Verify that it was added to host cache, by doing a subsequent async lookup
8159 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078160 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238161 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8162 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328163 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288164
bncce36dca22015-04-21 22:11:238165 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288166 // we can tell if the next lookup hit the cache, or the "network".
8167 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238168 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288169
8170 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8171 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068172 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398173 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078174 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288175
[email protected]3b9cca42009-06-16 01:08:288176 // Run the request.
[email protected]49639fa2011-12-20 23:22:418177 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288178 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418179 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288180
8181 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238182 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288183 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8184}
8185
[email protected]685af592010-05-11 19:31:248186// There are multiple load flags that should trigger the host cache bypass.
8187// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028188TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248189 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8190}
8191
[email protected]23e482282013-06-14 16:08:028192TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248193 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8194}
8195
[email protected]23e482282013-06-14 16:08:028196TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248197 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8198}
8199
[email protected]0877e3d2009-10-17 22:29:578200// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028201TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578202 HttpRequestInfo request;
8203 request.method = "GET";
8204 request.url = GURL("http://www.foo.com/");
8205 request.load_flags = 0;
8206
8207 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068208 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578209 };
[email protected]31a2bfe2010-02-09 08:03:398210 StaticSocketDataProvider data(NULL, 0,
8211 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078212 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078213 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578214
[email protected]49639fa2011-12-20 23:22:418215 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578216
8217 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418218 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578219
[email protected]49639fa2011-12-20 23:22:418220 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578221 EXPECT_EQ(ERR_IO_PENDING, rv);
8222
8223 rv = callback.WaitForResult();
8224 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8225}
8226
zmo9528c9f42015-08-04 22:12:088227// Check that a connection closed after the start of the headers finishes ok.
8228TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578229 HttpRequestInfo request;
8230 request.method = "GET";
8231 request.url = GURL("http://www.foo.com/");
8232 request.load_flags = 0;
8233
8234 MockRead data_reads[] = {
8235 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068236 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578237 };
8238
[email protected]31a2bfe2010-02-09 08:03:398239 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078240 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078241 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578242
[email protected]49639fa2011-12-20 23:22:418243 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578244
8245 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418246 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578247
[email protected]49639fa2011-12-20 23:22:418248 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578249 EXPECT_EQ(ERR_IO_PENDING, rv);
8250
8251 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:088252 EXPECT_EQ(OK, rv);
8253
8254 const HttpResponseInfo* response = trans->GetResponseInfo();
8255 ASSERT_TRUE(response != NULL);
8256
8257 EXPECT_TRUE(response->headers.get() != NULL);
8258 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8259
8260 std::string response_data;
8261 rv = ReadTransaction(trans.get(), &response_data);
8262 EXPECT_EQ(OK, rv);
8263 EXPECT_EQ("", response_data);
[email protected]0877e3d2009-10-17 22:29:578264}
8265
8266// Make sure that a dropped connection while draining the body for auth
8267// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028268TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578269 HttpRequestInfo request;
8270 request.method = "GET";
bncce36dca22015-04-21 22:11:238271 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578272 request.load_flags = 0;
8273
8274 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238275 MockWrite(
8276 "GET / HTTP/1.1\r\n"
8277 "Host: www.example.org\r\n"
8278 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578279 };
8280
8281 MockRead data_reads1[] = {
8282 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8283 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8284 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8285 MockRead("Content-Length: 14\r\n\r\n"),
8286 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068287 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578288 };
8289
[email protected]31a2bfe2010-02-09 08:03:398290 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8291 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078292 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578293
8294 // After calling trans->RestartWithAuth(), this is the request we should
8295 // be issuing -- the final header line contains the credentials.
8296 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238297 MockWrite(
8298 "GET / HTTP/1.1\r\n"
8299 "Host: www.example.org\r\n"
8300 "Connection: keep-alive\r\n"
8301 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578302 };
8303
8304 // Lastly, the server responds with the actual content.
8305 MockRead data_reads2[] = {
8306 MockRead("HTTP/1.1 200 OK\r\n"),
8307 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8308 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068309 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578310 };
8311
[email protected]31a2bfe2010-02-09 08:03:398312 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8313 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078314 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:078315 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578316
[email protected]49639fa2011-12-20 23:22:418317 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578318
[email protected]262eec82013-03-19 21:01:368319 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508320 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508321
[email protected]49639fa2011-12-20 23:22:418322 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578323 EXPECT_EQ(ERR_IO_PENDING, rv);
8324
8325 rv = callback1.WaitForResult();
8326 EXPECT_EQ(OK, rv);
8327
8328 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508329 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048330 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578331
[email protected]49639fa2011-12-20 23:22:418332 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578333
[email protected]49639fa2011-12-20 23:22:418334 rv = trans->RestartWithAuth(
8335 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578336 EXPECT_EQ(ERR_IO_PENDING, rv);
8337
8338 rv = callback2.WaitForResult();
8339 EXPECT_EQ(OK, rv);
8340
8341 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508342 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578343 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8344 EXPECT_EQ(100, response->headers->GetContentLength());
8345}
8346
8347// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028348TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078349 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578350
8351 HttpRequestInfo request;
8352 request.method = "GET";
bncce36dca22015-04-21 22:11:238353 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578354 request.load_flags = 0;
8355
8356 MockRead proxy_reads[] = {
8357 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068358 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578359 };
8360
[email protected]31a2bfe2010-02-09 08:03:398361 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068362 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578363
[email protected]bb88e1d32013-05-03 23:11:078364 session_deps_.socket_factory->AddSocketDataProvider(&data);
8365 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578366
[email protected]49639fa2011-12-20 23:22:418367 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578368
[email protected]bb88e1d32013-05-03 23:11:078369 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578370
[email protected]3fe8d2f82013-10-17 08:56:078371 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578372 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418373 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578374
[email protected]49639fa2011-12-20 23:22:418375 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578376 EXPECT_EQ(ERR_IO_PENDING, rv);
8377
8378 rv = callback.WaitForResult();
8379 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8380}
8381
[email protected]23e482282013-06-14 16:08:028382TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468383 HttpRequestInfo request;
8384 request.method = "GET";
bncce36dca22015-04-21 22:11:238385 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468386 request.load_flags = 0;
8387
[email protected]3fe8d2f82013-10-17 08:56:078388 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278389 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418390 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278391
[email protected]e22e1362009-11-23 21:31:128392 MockRead data_reads[] = {
8393 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068394 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128395 };
[email protected]9492e4a2010-02-24 00:58:468396
8397 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078398 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468399
[email protected]49639fa2011-12-20 23:22:418400 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468401
[email protected]49639fa2011-12-20 23:22:418402 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468403 EXPECT_EQ(ERR_IO_PENDING, rv);
8404
8405 EXPECT_EQ(OK, callback.WaitForResult());
8406
8407 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508408 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468409
[email protected]90499482013-06-01 00:39:508410 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468411 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8412
8413 std::string response_data;
8414 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238415 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128416}
8417
[email protected]23e482282013-06-14 16:08:028418TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158419 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528420 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338421 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218422 UploadFileElementReader::ScopedOverridingContentLengthForTests
8423 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338424
[email protected]b2d26cfd2012-12-11 10:36:068425 ScopedVector<UploadElementReader> element_readers;
8426 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458427 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8428 temp_file_path, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078429 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278430
8431 HttpRequestInfo request;
8432 request.method = "POST";
bncce36dca22015-04-21 22:11:238433 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278434 request.upload_data_stream = &upload_data_stream;
8435 request.load_flags = 0;
8436
[email protected]3fe8d2f82013-10-17 08:56:078437 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278438 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418439 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338440
8441 MockRead data_reads[] = {
8442 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8443 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068444 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338445 };
[email protected]31a2bfe2010-02-09 08:03:398446 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078447 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338448
[email protected]49639fa2011-12-20 23:22:418449 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338450
[email protected]49639fa2011-12-20 23:22:418451 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338452 EXPECT_EQ(ERR_IO_PENDING, rv);
8453
8454 rv = callback.WaitForResult();
8455 EXPECT_EQ(OK, rv);
8456
8457 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508458 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338459
[email protected]90499482013-06-01 00:39:508460 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338461 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8462
8463 std::string response_data;
8464 rv = ReadTransaction(trans.get(), &response_data);
8465 EXPECT_EQ(OK, rv);
8466 EXPECT_EQ("hello world", response_data);
8467
[email protected]dd3aa792013-07-16 19:10:238468 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338469}
8470
[email protected]23e482282013-06-14 16:08:028471TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158472 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528473 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368474 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308475 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368476 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118477 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368478
[email protected]b2d26cfd2012-12-11 10:36:068479 ScopedVector<UploadElementReader> element_readers;
8480 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458481 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8482 temp_file, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078483 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278484
8485 HttpRequestInfo request;
8486 request.method = "POST";
bncce36dca22015-04-21 22:11:238487 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278488 request.upload_data_stream = &upload_data_stream;
8489 request.load_flags = 0;
8490
[email protected]999dd8c2013-11-12 06:45:548491 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078492 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278493 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418494 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368495
[email protected]999dd8c2013-11-12 06:45:548496 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078497 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368498
[email protected]49639fa2011-12-20 23:22:418499 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368500
[email protected]49639fa2011-12-20 23:22:418501 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368502 EXPECT_EQ(ERR_IO_PENDING, rv);
8503
8504 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548505 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368506
[email protected]dd3aa792013-07-16 19:10:238507 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368508}
8509
[email protected]02cad5d2013-10-02 08:14:038510TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8511 class FakeUploadElementReader : public UploadElementReader {
8512 public:
8513 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208514 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038515
8516 const CompletionCallback& callback() const { return callback_; }
8517
8518 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208519 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038520 callback_ = callback;
8521 return ERR_IO_PENDING;
8522 }
dchengb03027d2014-10-21 12:00:208523 uint64 GetContentLength() const override { return 0; }
8524 uint64 BytesRemaining() const override { return 0; }
8525 int Read(IOBuffer* buf,
8526 int buf_length,
8527 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038528 return ERR_FAILED;
8529 }
8530
8531 private:
8532 CompletionCallback callback_;
8533 };
8534
8535 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8536 ScopedVector<UploadElementReader> element_readers;
8537 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078538 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038539
8540 HttpRequestInfo request;
8541 request.method = "POST";
bncce36dca22015-04-21 22:11:238542 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038543 request.upload_data_stream = &upload_data_stream;
8544 request.load_flags = 0;
8545
[email protected]3fe8d2f82013-10-17 08:56:078546 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038547 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418548 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038549
8550 StaticSocketDataProvider data;
8551 session_deps_.socket_factory->AddSocketDataProvider(&data);
8552
8553 TestCompletionCallback callback;
8554 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8555 EXPECT_EQ(ERR_IO_PENDING, rv);
8556 base::MessageLoop::current()->RunUntilIdle();
8557
8558 // Transaction is pending on request body initialization.
8559 ASSERT_FALSE(fake_reader->callback().is_null());
8560
8561 // Return Init()'s result after the transaction gets destroyed.
8562 trans.reset();
8563 fake_reader->callback().Run(OK); // Should not crash.
8564}
8565
[email protected]aeefc9e82010-02-19 16:18:278566// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028567TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278568 HttpRequestInfo request;
8569 request.method = "GET";
bncce36dca22015-04-21 22:11:238570 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278571 request.load_flags = 0;
8572
8573 // First transaction will request a resource and receive a Basic challenge
8574 // with realm="first_realm".
8575 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238576 MockWrite(
8577 "GET / HTTP/1.1\r\n"
8578 "Host: www.example.org\r\n"
8579 "Connection: keep-alive\r\n"
8580 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278581 };
8582 MockRead data_reads1[] = {
8583 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8584 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8585 "\r\n"),
8586 };
8587
8588 // After calling trans->RestartWithAuth(), provide an Authentication header
8589 // for first_realm. The server will reject and provide a challenge with
8590 // second_realm.
8591 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238592 MockWrite(
8593 "GET / HTTP/1.1\r\n"
8594 "Host: www.example.org\r\n"
8595 "Connection: keep-alive\r\n"
8596 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8597 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278598 };
8599 MockRead data_reads2[] = {
8600 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8601 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8602 "\r\n"),
8603 };
8604
8605 // This again fails, and goes back to first_realm. Make sure that the
8606 // entry is removed from cache.
8607 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238608 MockWrite(
8609 "GET / HTTP/1.1\r\n"
8610 "Host: www.example.org\r\n"
8611 "Connection: keep-alive\r\n"
8612 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8613 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278614 };
8615 MockRead data_reads3[] = {
8616 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8617 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8618 "\r\n"),
8619 };
8620
8621 // Try one last time (with the correct password) and get the resource.
8622 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238623 MockWrite(
8624 "GET / HTTP/1.1\r\n"
8625 "Host: www.example.org\r\n"
8626 "Connection: keep-alive\r\n"
8627 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8628 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278629 };
8630 MockRead data_reads4[] = {
8631 MockRead("HTTP/1.1 200 OK\r\n"
8632 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508633 "Content-Length: 5\r\n"
8634 "\r\n"
8635 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278636 };
8637
8638 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8639 data_writes1, arraysize(data_writes1));
8640 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8641 data_writes2, arraysize(data_writes2));
8642 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8643 data_writes3, arraysize(data_writes3));
8644 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8645 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078646 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8647 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8648 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8649 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278650
[email protected]49639fa2011-12-20 23:22:418651 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278652
[email protected]3fe8d2f82013-10-17 08:56:078653 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508654 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418655 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508656
[email protected]aeefc9e82010-02-19 16:18:278657 // Issue the first request with Authorize headers. There should be a
8658 // password prompt for first_realm waiting to be filled in after the
8659 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418660 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278661 EXPECT_EQ(ERR_IO_PENDING, rv);
8662 rv = callback1.WaitForResult();
8663 EXPECT_EQ(OK, rv);
8664 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508665 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048666 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8667 ASSERT_FALSE(challenge == NULL);
8668 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238669 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048670 EXPECT_EQ("first_realm", challenge->realm);
8671 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278672
8673 // Issue the second request with an incorrect password. There should be a
8674 // password prompt for second_realm waiting to be filled in after the
8675 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418676 TestCompletionCallback callback2;
8677 rv = trans->RestartWithAuth(
8678 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278679 EXPECT_EQ(ERR_IO_PENDING, rv);
8680 rv = callback2.WaitForResult();
8681 EXPECT_EQ(OK, rv);
8682 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508683 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048684 challenge = response->auth_challenge.get();
8685 ASSERT_FALSE(challenge == NULL);
8686 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238687 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048688 EXPECT_EQ("second_realm", challenge->realm);
8689 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278690
8691 // Issue the third request with another incorrect password. There should be
8692 // a password prompt for first_realm waiting to be filled in. If the password
8693 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8694 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418695 TestCompletionCallback callback3;
8696 rv = trans->RestartWithAuth(
8697 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278698 EXPECT_EQ(ERR_IO_PENDING, rv);
8699 rv = callback3.WaitForResult();
8700 EXPECT_EQ(OK, rv);
8701 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508702 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048703 challenge = response->auth_challenge.get();
8704 ASSERT_FALSE(challenge == NULL);
8705 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238706 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048707 EXPECT_EQ("first_realm", challenge->realm);
8708 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278709
8710 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418711 TestCompletionCallback callback4;
8712 rv = trans->RestartWithAuth(
8713 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278714 EXPECT_EQ(ERR_IO_PENDING, rv);
8715 rv = callback4.WaitForResult();
8716 EXPECT_EQ(OK, rv);
8717 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508718 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278719 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8720}
8721
bncc958faa2015-07-31 18:14:528722TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
8723 session_deps_.next_protos = SpdyNextProtos();
8724 session_deps_.use_alternate_protocols = true;
8725
8726 std::string alternative_service_http_header =
8727 GetAlternativeServiceHttpHeader();
8728
8729 MockRead data_reads[] = {
8730 MockRead("HTTP/1.1 200 OK\r\n"),
8731 MockRead(alternative_service_http_header.c_str()),
8732 MockRead("\r\n"),
8733 MockRead("hello world"),
8734 MockRead(SYNCHRONOUS, OK),
8735 };
8736
8737 HttpRequestInfo request;
8738 request.method = "GET";
8739 request.url = GURL("http://www.example.org/");
8740 request.load_flags = 0;
8741
8742 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8743
8744 session_deps_.socket_factory->AddSocketDataProvider(&data);
8745
8746 TestCompletionCallback callback;
8747
8748 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8749 scoped_ptr<HttpTransaction> trans(
8750 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8751
8752 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8753 EXPECT_EQ(ERR_IO_PENDING, rv);
8754
8755 HostPortPair http_host_port_pair("www.example.org", 80);
8756 HttpServerProperties& http_server_properties =
8757 *session->http_server_properties();
8758 AlternativeServiceVector alternative_service_vector =
8759 http_server_properties.GetAlternativeServices(http_host_port_pair);
8760 EXPECT_TRUE(alternative_service_vector.empty());
8761
8762 EXPECT_EQ(OK, callback.WaitForResult());
8763
8764 const HttpResponseInfo* response = trans->GetResponseInfo();
8765 ASSERT_TRUE(response != NULL);
8766 ASSERT_TRUE(response->headers.get() != NULL);
8767 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8768 EXPECT_FALSE(response->was_fetched_via_spdy);
8769 EXPECT_FALSE(response->was_npn_negotiated);
8770
8771 std::string response_data;
8772 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8773 EXPECT_EQ("hello world", response_data);
8774
8775 alternative_service_vector =
8776 http_server_properties.GetAlternativeServices(http_host_port_pair);
8777 ASSERT_EQ(1u, alternative_service_vector.size());
8778 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
8779 alternative_service_vector[0].protocol);
8780 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
8781 EXPECT_EQ(443, alternative_service_vector[0].port);
8782}
8783
8784TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
8785 session_deps_.next_protos = SpdyNextProtos();
8786 session_deps_.use_alternate_protocols = true;
8787
8788 MockRead data_reads[] = {
8789 MockRead("HTTP/1.1 200 OK\r\n"),
8790 MockRead("Alt-Svc: "),
8791 MockRead(GetAlternateProtocolFromParam()),
8792 MockRead("=\"www.example.com:443\";p=1.0,"),
8793 MockRead("quic=\":1234\"\r\n\r\n"),
8794 MockRead("hello world"),
8795 MockRead(SYNCHRONOUS, OK),
8796 };
8797
8798 HttpRequestInfo request;
8799 request.method = "GET";
8800 request.url = GURL("http://www.example.org/");
8801 request.load_flags = 0;
8802
8803 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8804
8805 session_deps_.socket_factory->AddSocketDataProvider(&data);
8806
8807 TestCompletionCallback callback;
8808
8809 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8810 scoped_ptr<HttpTransaction> trans(
8811 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8812
8813 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8814 EXPECT_EQ(ERR_IO_PENDING, rv);
8815
8816 HostPortPair http_host_port_pair("www.example.org", 80);
8817 HttpServerProperties& http_server_properties =
8818 *session->http_server_properties();
8819 AlternativeServiceVector alternative_service_vector =
8820 http_server_properties.GetAlternativeServices(http_host_port_pair);
8821 EXPECT_TRUE(alternative_service_vector.empty());
8822
8823 EXPECT_EQ(OK, callback.WaitForResult());
8824
8825 const HttpResponseInfo* response = trans->GetResponseInfo();
8826 ASSERT_TRUE(response != NULL);
8827 ASSERT_TRUE(response->headers.get() != NULL);
8828 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8829 EXPECT_FALSE(response->was_fetched_via_spdy);
8830 EXPECT_FALSE(response->was_npn_negotiated);
8831
8832 std::string response_data;
8833 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8834 EXPECT_EQ("hello world", response_data);
8835
8836 alternative_service_vector =
8837 http_server_properties.GetAlternativeServices(http_host_port_pair);
8838 ASSERT_EQ(2u, alternative_service_vector.size());
8839 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
8840 alternative_service_vector[0].protocol);
8841 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
8842 EXPECT_EQ(443, alternative_service_vector[0].port);
8843 EXPECT_EQ(QUIC, alternative_service_vector[1].protocol);
8844 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
8845 EXPECT_EQ(1234, alternative_service_vector[1].port);
8846}
8847
[email protected]23e482282013-06-14 16:08:028848TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238849 session_deps_.next_protos = SpdyNextProtos();
8850 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428851
[email protected]8a0fc822013-06-27 20:52:438852 std::string alternate_protocol_http_header =
8853 GetAlternateProtocolHttpHeader();
8854
[email protected]564b4912010-03-09 16:30:428855 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:528856 MockRead("HTTP/1.1 200 OK\r\n"),
8857 MockRead(alternate_protocol_http_header.c_str()),
8858 MockRead("\r\n"),
8859 MockRead("hello world"),
8860 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428861 };
8862
8863 HttpRequestInfo request;
8864 request.method = "GET";
bncce36dca22015-04-21 22:11:238865 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428866 request.load_flags = 0;
8867
8868 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8869
[email protected]bb88e1d32013-05-03 23:11:078870 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428871
[email protected]49639fa2011-12-20 23:22:418872 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428873
[email protected]bb88e1d32013-05-03 23:11:078874 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368875 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508876 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428877
[email protected]49639fa2011-12-20 23:22:418878 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428879 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538880
bncce36dca22015-04-21 22:11:238881 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:558882 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538883 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:108884 AlternativeServiceVector alternative_service_vector =
8885 http_server_properties.GetAlternativeServices(http_host_port_pair);
8886 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:428887
8888 EXPECT_EQ(OK, callback.WaitForResult());
8889
8890 const HttpResponseInfo* response = trans->GetResponseInfo();
8891 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508892 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428893 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538894 EXPECT_FALSE(response->was_fetched_via_spdy);
8895 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428896
8897 std::string response_data;
8898 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8899 EXPECT_EQ("hello world", response_data);
8900
bncd9b132e2015-07-08 05:16:108901 alternative_service_vector =
8902 http_server_properties.GetAlternativeServices(http_host_port_pair);
8903 ASSERT_EQ(1u, alternative_service_vector.size());
8904 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc181b39a2015-03-17 21:36:478905 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
bncd9b132e2015-07-08 05:16:108906 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:428907}
8908
rch89c6e102015-03-18 18:56:528909TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
8910 session_deps_.next_protos = SpdyNextProtos();
8911 session_deps_.use_alternate_protocols = true;
8912
8913 MockRead data_reads[] = {
8914 MockRead("HTTP/1.1 200 OK\r\n"),
8915 MockRead("Alternate-Protocol: \r\n\r\n"),
8916 MockRead("hello world"),
8917 MockRead(SYNCHRONOUS, OK),
8918 };
8919
8920 HttpRequestInfo request;
8921 request.method = "GET";
bncce36dca22015-04-21 22:11:238922 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:528923 request.load_flags = 0;
8924
8925 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8926
8927 session_deps_.socket_factory->AddSocketDataProvider(&data);
8928
8929 TestCompletionCallback callback;
8930
8931 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8932
bncce36dca22015-04-21 22:11:238933 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:528934 HttpServerProperties& http_server_properties =
8935 *session->http_server_properties();
bnccacc0992015-03-20 20:22:228936 AlternativeService alternative_service(QUIC, "", 80);
bnc7dc7e1b42015-07-28 14:43:128937 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
8938 http_server_properties.SetAlternativeService(
8939 http_host_port_pair, alternative_service, 1.0, expiration);
bnccacc0992015-03-20 20:22:228940
bncd9b132e2015-07-08 05:16:108941 AlternativeServiceVector alternative_service_vector =
8942 http_server_properties.GetAlternativeServices(http_host_port_pair);
8943 ASSERT_EQ(1u, alternative_service_vector.size());
8944 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:528945
8946 scoped_ptr<HttpTransaction> trans(
8947 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8948
8949 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8950 EXPECT_EQ(ERR_IO_PENDING, rv);
8951
8952 EXPECT_EQ(OK, callback.WaitForResult());
8953
8954 const HttpResponseInfo* response = trans->GetResponseInfo();
8955 ASSERT_TRUE(response != NULL);
8956 ASSERT_TRUE(response->headers.get() != NULL);
8957 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8958 EXPECT_FALSE(response->was_fetched_via_spdy);
8959 EXPECT_FALSE(response->was_npn_negotiated);
8960
8961 std::string response_data;
8962 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8963 EXPECT_EQ("hello world", response_data);
8964
bncd9b132e2015-07-08 05:16:108965 alternative_service_vector =
8966 http_server_properties.GetAlternativeServices(http_host_port_pair);
8967 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:528968}
8969
bncc958faa2015-07-31 18:14:528970TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
8971 session_deps_.next_protos = SpdyNextProtos();
8972 session_deps_.use_alternate_protocols = true;
8973
8974 std::string alternative_service_http_header =
8975 GetAlternativeServiceHttpHeader();
8976 std::string alternate_protocol_http_header = GetAlternateProtocolHttpHeader();
8977
8978 MockRead data_reads[] = {
8979 MockRead("HTTP/1.1 200 OK\r\n"),
8980 MockRead(alternative_service_http_header.c_str()),
8981 MockRead(alternate_protocol_http_header.c_str()),
8982 MockRead("\r\n"),
8983 MockRead("hello world"),
8984 MockRead(SYNCHRONOUS, OK),
8985 };
8986
8987 HttpRequestInfo request;
8988 request.method = "GET";
8989 request.url = GURL("http://www.example.org/");
8990 request.load_flags = 0;
8991
8992 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8993
8994 session_deps_.socket_factory->AddSocketDataProvider(&data);
8995
8996 TestCompletionCallback callback;
8997
8998 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8999 scoped_ptr<HttpTransaction> trans(
9000 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9001
9002 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9003 EXPECT_EQ(ERR_IO_PENDING, rv);
9004
9005 HostPortPair http_host_port_pair("www.example.org", 80);
9006 HttpServerProperties& http_server_properties =
9007 *session->http_server_properties();
9008 AlternativeServiceVector alternative_service_vector =
9009 http_server_properties.GetAlternativeServices(http_host_port_pair);
9010 EXPECT_TRUE(alternative_service_vector.empty());
9011
9012 EXPECT_EQ(OK, callback.WaitForResult());
9013
9014 const HttpResponseInfo* response = trans->GetResponseInfo();
9015 ASSERT_TRUE(response != NULL);
9016 ASSERT_TRUE(response->headers.get() != NULL);
9017 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9018 EXPECT_FALSE(response->was_fetched_via_spdy);
9019 EXPECT_FALSE(response->was_npn_negotiated);
9020
9021 std::string response_data;
9022 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9023 EXPECT_EQ("hello world", response_data);
9024
9025 alternative_service_vector =
9026 http_server_properties.GetAlternativeServices(http_host_port_pair);
9027 ASSERT_EQ(1u, alternative_service_vector.size());
9028 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9029 alternative_service_vector[0].protocol);
9030 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9031 EXPECT_EQ(443, alternative_service_vector[0].port);
9032}
9033
[email protected]23e482282013-06-14 16:08:029034TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239035 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:239036 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:429037
9038 HttpRequestInfo request;
9039 request.method = "GET";
bncce36dca22015-04-21 22:11:239040 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429041 request.load_flags = 0;
9042
[email protected]d973e99a2012-02-17 21:02:369043 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:429044 StaticSocketDataProvider first_data;
9045 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079046 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:429047
9048 MockRead data_reads[] = {
9049 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9050 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069051 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:429052 };
9053 StaticSocketDataProvider second_data(
9054 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079055 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:429056
[email protected]bb88e1d32013-05-03 23:11:079057 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:429058
[email protected]30d4c022013-07-18 22:58:169059 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539060 session->http_server_properties();
bnc8445b3002015-03-13 01:57:099061 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:119062 // Port must be < 1024, or the header will be ignored (since initial port was
9063 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:109064 const AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239065 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bncd9b132e2015-07-08 05:16:109066 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:129067 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9068 http_server_properties->SetAlternativeService(
9069 host_port_pair, alternative_service, 1.0, expiration);
[email protected]564b4912010-03-09 16:30:429070
[email protected]262eec82013-03-19 21:01:369071 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509072 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419073 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429074
[email protected]49639fa2011-12-20 23:22:419075 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429076 EXPECT_EQ(ERR_IO_PENDING, rv);
9077 EXPECT_EQ(OK, callback.WaitForResult());
9078
9079 const HttpResponseInfo* response = trans->GetResponseInfo();
9080 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509081 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429082 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9083
9084 std::string response_data;
9085 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9086 EXPECT_EQ("hello world", response_data);
9087
bncd9b132e2015-07-08 05:16:109088 const AlternativeServiceVector alternative_service_vector =
9089 http_server_properties->GetAlternativeServices(host_port_pair);
9090 ASSERT_EQ(1u, alternative_service_vector.size());
9091 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
9092 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
9093 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:429094}
9095
[email protected]23e482282013-06-14 16:08:029096TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239097 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:119098 // Ensure that we're not allowed to redirect traffic via an alternate
9099 // protocol to an unrestricted (port >= 1024) when the original traffic was
9100 // on a restricted port (port < 1024). Ensure that we can redirect in all
9101 // other cases.
[email protected]d7599122014-05-24 03:37:239102 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119103
9104 HttpRequestInfo restricted_port_request;
9105 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239106 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119107 restricted_port_request.load_flags = 0;
9108
[email protected]d973e99a2012-02-17 21:02:369109 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119110 StaticSocketDataProvider first_data;
9111 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079112 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119113
9114 MockRead data_reads[] = {
9115 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9116 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069117 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119118 };
9119 StaticSocketDataProvider second_data(
9120 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079121 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119122
[email protected]bb88e1d32013-05-03 23:11:079123 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119124
[email protected]30d4c022013-07-18 22:58:169125 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539126 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119127 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229128 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239129 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229130 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129131 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229132 http_server_properties->SetAlternativeService(
9133 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129134 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119135
[email protected]262eec82013-03-19 21:01:369136 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419138 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119139
[email protected]49639fa2011-12-20 23:22:419140 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369141 &restricted_port_request,
9142 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119143 EXPECT_EQ(ERR_IO_PENDING, rv);
9144 // Invalid change to unrestricted port should fail.
9145 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:199146}
[email protected]3912662a32011-10-04 00:51:119147
[email protected]23e482282013-06-14 16:08:029148TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:199149 AlternateProtocolPortRestrictedPermitted) {
9150 // Ensure that we're allowed to redirect traffic via an alternate
9151 // protocol to an unrestricted (port >= 1024) when the original traffic was
9152 // on a restricted port (port < 1024) if we set
9153 // enable_user_alternate_protocol_ports.
9154
[email protected]d7599122014-05-24 03:37:239155 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:079156 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:199157
9158 HttpRequestInfo restricted_port_request;
9159 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239160 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:199161 restricted_port_request.load_flags = 0;
9162
9163 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9164 StaticSocketDataProvider first_data;
9165 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079166 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:199167
9168 MockRead data_reads[] = {
9169 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9170 MockRead("hello world"),
9171 MockRead(ASYNC, OK),
9172 };
9173 StaticSocketDataProvider second_data(
9174 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079175 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:199176
[email protected]bb88e1d32013-05-03 23:11:079177 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:199178
[email protected]30d4c022013-07-18 22:58:169179 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:199180 session->http_server_properties();
9181 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229182 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239183 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229184 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129185 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229186 http_server_properties->SetAlternativeService(
9187 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129188 1.0, expiration);
[email protected]c54c6962013-02-01 04:53:199189
[email protected]262eec82013-03-19 21:01:369190 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:199192 TestCompletionCallback callback;
9193
9194 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:369195 &restricted_port_request,
9196 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:199197 // Change to unrestricted port should succeed.
9198 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119199}
9200
[email protected]23e482282013-06-14 16:08:029201TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239202 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:119203 // Ensure that we're not allowed to redirect traffic via an alternate
9204 // protocol to an unrestricted (port >= 1024) when the original traffic was
9205 // on a restricted port (port < 1024). Ensure that we can redirect in all
9206 // other cases.
[email protected]d7599122014-05-24 03:37:239207 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119208
9209 HttpRequestInfo restricted_port_request;
9210 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239211 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119212 restricted_port_request.load_flags = 0;
9213
[email protected]d973e99a2012-02-17 21:02:369214 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119215 StaticSocketDataProvider first_data;
9216 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079217 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119218
9219 MockRead data_reads[] = {
9220 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9221 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069222 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119223 };
9224 StaticSocketDataProvider second_data(
9225 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079226 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119227
[email protected]bb88e1d32013-05-03 23:11:079228 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119229
[email protected]30d4c022013-07-18 22:58:169230 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539231 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119232 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229233 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239234 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229235 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129236 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229237 http_server_properties->SetAlternativeService(
9238 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129239 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119240
[email protected]262eec82013-03-19 21:01:369241 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509242 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419243 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119244
[email protected]49639fa2011-12-20 23:22:419245 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369246 &restricted_port_request,
9247 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119248 EXPECT_EQ(ERR_IO_PENDING, rv);
9249 // Valid change to restricted port should pass.
9250 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119251}
9252
[email protected]23e482282013-06-14 16:08:029253TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239254 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:119255 // Ensure that we're not allowed to redirect traffic via an alternate
9256 // protocol to an unrestricted (port >= 1024) when the original traffic was
9257 // on a restricted port (port < 1024). Ensure that we can redirect in all
9258 // other cases.
[email protected]d7599122014-05-24 03:37:239259 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119260
9261 HttpRequestInfo unrestricted_port_request;
9262 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239263 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119264 unrestricted_port_request.load_flags = 0;
9265
[email protected]d973e99a2012-02-17 21:02:369266 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119267 StaticSocketDataProvider first_data;
9268 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079269 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119270
9271 MockRead data_reads[] = {
9272 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9273 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069274 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119275 };
9276 StaticSocketDataProvider second_data(
9277 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079278 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119279
[email protected]bb88e1d32013-05-03 23:11:079280 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119281
[email protected]30d4c022013-07-18 22:58:169282 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539283 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119284 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229285 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239286 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229287 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129288 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229289 http_server_properties->SetAlternativeService(
9290 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129291 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119292
[email protected]262eec82013-03-19 21:01:369293 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509294 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419295 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119296
[email protected]49639fa2011-12-20 23:22:419297 int rv = trans->Start(
9298 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119299 EXPECT_EQ(ERR_IO_PENDING, rv);
9300 // Valid change to restricted port should pass.
9301 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119302}
9303
[email protected]23e482282013-06-14 16:08:029304TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239305 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:119306 // Ensure that we're not allowed to redirect traffic via an alternate
9307 // protocol to an unrestricted (port >= 1024) when the original traffic was
9308 // on a restricted port (port < 1024). Ensure that we can redirect in all
9309 // other cases.
[email protected]d7599122014-05-24 03:37:239310 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119311
9312 HttpRequestInfo unrestricted_port_request;
9313 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239314 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119315 unrestricted_port_request.load_flags = 0;
9316
[email protected]d973e99a2012-02-17 21:02:369317 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119318 StaticSocketDataProvider first_data;
9319 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079320 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119321
9322 MockRead data_reads[] = {
9323 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9324 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069325 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119326 };
9327 StaticSocketDataProvider second_data(
9328 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079329 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119330
[email protected]bb88e1d32013-05-03 23:11:079331 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119332
[email protected]30d4c022013-07-18 22:58:169333 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539334 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:229335 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:229336 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239337 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229338 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129339 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229340 http_server_properties->SetAlternativeService(
9341 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129342 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119343
[email protected]262eec82013-03-19 21:01:369344 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419346 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119347
[email protected]49639fa2011-12-20 23:22:419348 int rv = trans->Start(
9349 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119350 EXPECT_EQ(ERR_IO_PENDING, rv);
9351 // Valid change to an unrestricted port should pass.
9352 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119353}
9354
[email protected]d7599122014-05-24 03:37:239355TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:029356 // Ensure that we're not allowed to redirect traffic via an alternate
9357 // protocol to an unsafe port, and that we resume the second
9358 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239359 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:029360
9361 HttpRequestInfo request;
9362 request.method = "GET";
bncce36dca22015-04-21 22:11:239363 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029364 request.load_flags = 0;
9365
9366 // The alternate protocol request will error out before we attempt to connect,
9367 // so only the standard HTTP request will try to connect.
9368 MockRead data_reads[] = {
9369 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9370 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069371 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029372 };
9373 StaticSocketDataProvider data(
9374 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079375 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029376
[email protected]bb88e1d32013-05-03 23:11:079377 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029378
[email protected]30d4c022013-07-18 22:58:169379 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029380 session->http_server_properties();
9381 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229382 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239383 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229384 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:129385 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229386 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:129387 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
[email protected]eb6234e2012-01-19 01:50:029388
[email protected]262eec82013-03-19 21:01:369389 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509390 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029391 TestCompletionCallback callback;
9392
9393 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9394 EXPECT_EQ(ERR_IO_PENDING, rv);
9395 // The HTTP request should succeed.
9396 EXPECT_EQ(OK, callback.WaitForResult());
9397
9398 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:239399 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:029400
9401 const HttpResponseInfo* response = trans->GetResponseInfo();
9402 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509403 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029404 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9405
9406 std::string response_data;
9407 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9408 EXPECT_EQ("hello world", response_data);
9409}
9410
[email protected]23e482282013-06-14 16:08:029411TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239412 session_deps_.use_alternate_protocols = true;
9413 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549414
9415 HttpRequestInfo request;
9416 request.method = "GET";
bncce36dca22015-04-21 22:11:239417 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549418 request.load_flags = 0;
9419
[email protected]8a0fc822013-06-27 20:52:439420 std::string alternate_protocol_http_header =
9421 GetAlternateProtocolHttpHeader();
9422
[email protected]2ff8b312010-04-26 22:20:549423 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529424 MockRead("HTTP/1.1 200 OK\r\n"),
9425 MockRead(alternate_protocol_http_header.c_str()),
9426 MockRead("\r\n"),
9427 MockRead("hello world"),
9428 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9429 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:549430
9431 StaticSocketDataProvider first_transaction(
9432 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079433 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549434
[email protected]8ddf8322012-02-23 18:08:069435 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029436 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239437 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9438 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079439 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549440
[email protected]cdf8f7e72013-05-23 10:56:469441 scoped_ptr<SpdyFrame> req(
9442 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139443 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549444
[email protected]23e482282013-06-14 16:08:029445 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9446 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549447 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139448 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549449 };
9450
rch8e6c6c42015-05-01 14:05:139451 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9452 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079453 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549454
[email protected]d973e99a2012-02-17 21:02:369455 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559456 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9457 NULL, 0, NULL, 0);
9458 hanging_non_alternate_protocol_socket.set_connect_data(
9459 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079460 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559461 &hanging_non_alternate_protocol_socket);
9462
[email protected]49639fa2011-12-20 23:22:419463 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549464
[email protected]bb88e1d32013-05-03 23:11:079465 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369466 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509467 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549468
[email protected]49639fa2011-12-20 23:22:419469 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549470 EXPECT_EQ(ERR_IO_PENDING, rv);
9471 EXPECT_EQ(OK, callback.WaitForResult());
9472
9473 const HttpResponseInfo* response = trans->GetResponseInfo();
9474 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509475 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549476 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9477
9478 std::string response_data;
9479 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9480 EXPECT_EQ("hello world", response_data);
9481
[email protected]90499482013-06-01 00:39:509482 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549483
[email protected]49639fa2011-12-20 23:22:419484 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549485 EXPECT_EQ(ERR_IO_PENDING, rv);
9486 EXPECT_EQ(OK, callback.WaitForResult());
9487
9488 response = trans->GetResponseInfo();
9489 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509490 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549491 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539492 EXPECT_TRUE(response->was_fetched_via_spdy);
9493 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549494
9495 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9496 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549497}
9498
[email protected]23e482282013-06-14 16:08:029499TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:239500 session_deps_.use_alternate_protocols = true;
9501 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559502
9503 HttpRequestInfo request;
9504 request.method = "GET";
bncce36dca22015-04-21 22:11:239505 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559506 request.load_flags = 0;
9507
[email protected]8a0fc822013-06-27 20:52:439508 std::string alternate_protocol_http_header =
9509 GetAlternateProtocolHttpHeader();
9510
[email protected]2d6728692011-03-12 01:39:559511 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529512 MockRead("HTTP/1.1 200 OK\r\n"),
9513 MockRead(alternate_protocol_http_header.c_str()),
9514 MockRead("\r\n"),
9515 MockRead("hello world"),
9516 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9517 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559518 };
9519
9520 StaticSocketDataProvider first_transaction(
9521 data_reads, arraysize(data_reads), NULL, 0);
9522 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079523 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559524
[email protected]d973e99a2012-02-17 21:02:369525 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559526 StaticSocketDataProvider hanging_socket(
9527 NULL, 0, NULL, 0);
9528 hanging_socket.set_connect_data(never_finishing_connect);
9529 // Socket 2 and 3 are the hanging Alternate-Protocol and
9530 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079531 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9532 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559533
[email protected]8ddf8322012-02-23 18:08:069534 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029535 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239536 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9537 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079538 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559539
[email protected]cdf8f7e72013-05-23 10:56:469540 scoped_ptr<SpdyFrame> req1(
9541 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9542 scoped_ptr<SpdyFrame> req2(
9543 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559544 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139545 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559546 };
[email protected]23e482282013-06-14 16:08:029547 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9548 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9549 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9550 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559551 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139552 CreateMockRead(*resp1, 2),
9553 CreateMockRead(*data1, 3),
9554 CreateMockRead(*resp2, 4),
9555 CreateMockRead(*data2, 5),
9556 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559557 };
9558
rch8e6c6c42015-05-01 14:05:139559 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9560 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559561 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079562 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559563
9564 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079565 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559566
[email protected]bb88e1d32013-05-03 23:11:079567 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419568 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509569 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559570
[email protected]49639fa2011-12-20 23:22:419571 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559572 EXPECT_EQ(ERR_IO_PENDING, rv);
9573 EXPECT_EQ(OK, callback1.WaitForResult());
9574
9575 const HttpResponseInfo* response = trans1.GetResponseInfo();
9576 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509577 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559578 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9579
9580 std::string response_data;
9581 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9582 EXPECT_EQ("hello world", response_data);
9583
[email protected]49639fa2011-12-20 23:22:419584 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509585 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419586 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559587 EXPECT_EQ(ERR_IO_PENDING, rv);
9588
[email protected]49639fa2011-12-20 23:22:419589 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509590 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419591 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559592 EXPECT_EQ(ERR_IO_PENDING, rv);
9593
9594 EXPECT_EQ(OK, callback2.WaitForResult());
9595 EXPECT_EQ(OK, callback3.WaitForResult());
9596
9597 response = trans2.GetResponseInfo();
9598 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509599 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559600 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9601 EXPECT_TRUE(response->was_fetched_via_spdy);
9602 EXPECT_TRUE(response->was_npn_negotiated);
9603 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9604 EXPECT_EQ("hello!", response_data);
9605
9606 response = trans3.GetResponseInfo();
9607 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509608 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559609 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9610 EXPECT_TRUE(response->was_fetched_via_spdy);
9611 EXPECT_TRUE(response->was_npn_negotiated);
9612 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9613 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559614}
9615
[email protected]23e482282013-06-14 16:08:029616TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239617 session_deps_.use_alternate_protocols = true;
9618 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559619
9620 HttpRequestInfo request;
9621 request.method = "GET";
bncce36dca22015-04-21 22:11:239622 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559623 request.load_flags = 0;
9624
[email protected]8a0fc822013-06-27 20:52:439625 std::string alternate_protocol_http_header =
9626 GetAlternateProtocolHttpHeader();
9627
[email protected]2d6728692011-03-12 01:39:559628 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529629 MockRead("HTTP/1.1 200 OK\r\n"),
9630 MockRead(alternate_protocol_http_header.c_str()),
9631 MockRead("\r\n"),
9632 MockRead("hello world"),
9633 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9634 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559635 };
9636
9637 StaticSocketDataProvider first_transaction(
9638 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079639 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559640
[email protected]8ddf8322012-02-23 18:08:069641 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029642 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079643 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559644
[email protected]d973e99a2012-02-17 21:02:369645 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559646 StaticSocketDataProvider hanging_alternate_protocol_socket(
9647 NULL, 0, NULL, 0);
9648 hanging_alternate_protocol_socket.set_connect_data(
9649 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079650 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559651 &hanging_alternate_protocol_socket);
9652
9653 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079654 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559655
[email protected]49639fa2011-12-20 23:22:419656 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559657
[email protected]bb88e1d32013-05-03 23:11:079658 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369659 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509660 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559661
[email protected]49639fa2011-12-20 23:22:419662 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559663 EXPECT_EQ(ERR_IO_PENDING, rv);
9664 EXPECT_EQ(OK, callback.WaitForResult());
9665
9666 const HttpResponseInfo* response = trans->GetResponseInfo();
9667 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509668 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559669 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9670
9671 std::string response_data;
9672 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9673 EXPECT_EQ("hello world", response_data);
9674
[email protected]90499482013-06-01 00:39:509675 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559676
[email protected]49639fa2011-12-20 23:22:419677 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559678 EXPECT_EQ(ERR_IO_PENDING, rv);
9679 EXPECT_EQ(OK, callback.WaitForResult());
9680
9681 response = trans->GetResponseInfo();
9682 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509683 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559684 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9685 EXPECT_FALSE(response->was_fetched_via_spdy);
9686 EXPECT_FALSE(response->was_npn_negotiated);
9687
9688 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9689 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559690}
9691
[email protected]631f1322010-04-30 17:59:119692class CapturingProxyResolver : public ProxyResolver {
9693 public:
sammce90c9212015-05-27 23:43:359694 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:209695 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119696
dchengb03027d2014-10-21 12:00:209697 int GetProxyForURL(const GURL& url,
9698 ProxyInfo* results,
9699 const CompletionCallback& callback,
9700 RequestHandle* request,
9701 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409702 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9703 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429704 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119705 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429706 return OK;
[email protected]631f1322010-04-30 17:59:119707 }
9708
dchengb03027d2014-10-21 12:00:209709 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119710
dchengb03027d2014-10-21 12:00:209711 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179712 NOTREACHED();
9713 return LOAD_STATE_IDLE;
9714 }
9715
[email protected]24476402010-07-20 20:55:179716 const std::vector<GURL>& resolved() const { return resolved_; }
9717
9718 private:
[email protected]631f1322010-04-30 17:59:119719 std::vector<GURL> resolved_;
9720
9721 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9722};
9723
sammce64b2362015-04-29 03:50:239724class CapturingProxyResolverFactory : public ProxyResolverFactory {
9725 public:
9726 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
9727 : ProxyResolverFactory(false), resolver_(resolver) {}
9728
9729 int CreateProxyResolver(
9730 const scoped_refptr<ProxyResolverScriptData>& pac_script,
9731 scoped_ptr<ProxyResolver>* resolver,
9732 const net::CompletionCallback& callback,
9733 scoped_ptr<Request>* request) override {
9734 resolver->reset(new ForwardingProxyResolver(resolver_));
9735 return OK;
9736 }
9737
9738 private:
9739 ProxyResolver* resolver_;
9740};
9741
[email protected]23e482282013-06-14 16:08:029742TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239743 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239744 session_deps_.use_alternate_protocols = true;
9745 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119746
9747 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429748 proxy_config.set_auto_detect(true);
9749 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119750
sammc5dd160c2015-04-02 02:43:139751 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:079752 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:139753 new ProxyConfigServiceFixed(proxy_config),
9754 make_scoped_ptr(
sammce64b2362015-04-29 03:50:239755 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:389756 NULL));
vishal.b62985ca92015-04-17 08:45:519757 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079758 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119759
9760 HttpRequestInfo request;
9761 request.method = "GET";
bncce36dca22015-04-21 22:11:239762 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:119763 request.load_flags = 0;
9764
[email protected]8a0fc822013-06-27 20:52:439765 std::string alternate_protocol_http_header =
9766 GetAlternateProtocolHttpHeader();
9767
[email protected]631f1322010-04-30 17:59:119768 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529769 MockRead("HTTP/1.1 200 OK\r\n"),
9770 MockRead(alternate_protocol_http_header.c_str()),
9771 MockRead("\r\n"),
9772 MockRead("hello world"),
9773 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9774 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119775 };
9776
9777 StaticSocketDataProvider first_transaction(
9778 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079779 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119780
[email protected]8ddf8322012-02-23 18:08:069781 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029782 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239783 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9784 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079785 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119786
[email protected]cdf8f7e72013-05-23 10:56:469787 scoped_ptr<SpdyFrame> req(
9788 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119789 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139790 MockWrite(ASYNC, 0,
9791 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9792 "Host: www.example.org\r\n"
9793 "Proxy-Connection: keep-alive\r\n\r\n"),
9794 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:119795 };
9796
[email protected]d911f1b2010-05-05 22:39:429797 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9798
[email protected]23e482282013-06-14 16:08:029799 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9800 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119801 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139802 MockRead(ASYNC, 1, kCONNECTResponse),
9803 CreateMockRead(*resp.get(), 3),
9804 CreateMockRead(*data.get(), 4),
9805 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:119806 };
9807
rch8e6c6c42015-05-01 14:05:139808 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9809 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079810 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119811
[email protected]d973e99a2012-02-17 21:02:369812 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559813 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9814 NULL, 0, NULL, 0);
9815 hanging_non_alternate_protocol_socket.set_connect_data(
9816 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079817 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559818 &hanging_non_alternate_protocol_socket);
9819
[email protected]49639fa2011-12-20 23:22:419820 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119821
[email protected]bb88e1d32013-05-03 23:11:079822 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369823 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509824 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119825
[email protected]49639fa2011-12-20 23:22:419826 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119827 EXPECT_EQ(ERR_IO_PENDING, rv);
9828 EXPECT_EQ(OK, callback.WaitForResult());
9829
9830 const HttpResponseInfo* response = trans->GetResponseInfo();
9831 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509832 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119833 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539834 EXPECT_FALSE(response->was_fetched_via_spdy);
9835 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119836
9837 std::string response_data;
9838 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9839 EXPECT_EQ("hello world", response_data);
9840
[email protected]90499482013-06-01 00:39:509841 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119842
[email protected]49639fa2011-12-20 23:22:419843 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119844 EXPECT_EQ(ERR_IO_PENDING, rv);
9845 EXPECT_EQ(OK, callback.WaitForResult());
9846
9847 response = trans->GetResponseInfo();
9848 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509849 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119850 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539851 EXPECT_TRUE(response->was_fetched_via_spdy);
9852 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119853
9854 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9855 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:139856 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:239857 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:139858 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:239859 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:139860 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119861
[email protected]029c83b62013-01-24 05:28:209862 LoadTimingInfo load_timing_info;
9863 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9864 TestLoadTimingNotReusedWithPac(load_timing_info,
9865 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119866}
[email protected]631f1322010-04-30 17:59:119867
[email protected]23e482282013-06-14 16:08:029868TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549869 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239870 session_deps_.use_alternate_protocols = true;
9871 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549872
9873 HttpRequestInfo request;
9874 request.method = "GET";
bncce36dca22015-04-21 22:11:239875 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549876 request.load_flags = 0;
9877
[email protected]8a0fc822013-06-27 20:52:439878 std::string alternate_protocol_http_header =
9879 GetAlternateProtocolHttpHeader();
9880
[email protected]2ff8b312010-04-26 22:20:549881 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529882 MockRead("HTTP/1.1 200 OK\r\n"),
9883 MockRead(alternate_protocol_http_header.c_str()),
9884 MockRead("\r\n"),
9885 MockRead("hello world"),
9886 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549887 };
9888
9889 StaticSocketDataProvider first_transaction(
9890 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079891 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549892
[email protected]8ddf8322012-02-23 18:08:069893 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029894 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239895 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9896 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079897 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549898
[email protected]cdf8f7e72013-05-23 10:56:469899 scoped_ptr<SpdyFrame> req(
9900 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139901 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549902
[email protected]23e482282013-06-14 16:08:029903 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9904 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549905 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139906 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549907 };
9908
rch8e6c6c42015-05-01 14:05:139909 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9910 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079911 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549912
[email protected]83039bb2011-12-09 18:43:559913 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549914
[email protected]bb88e1d32013-05-03 23:11:079915 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549916
[email protected]262eec82013-03-19 21:01:369917 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509918 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549919
[email protected]49639fa2011-12-20 23:22:419920 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549921 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419922 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549923
9924 const HttpResponseInfo* response = trans->GetResponseInfo();
9925 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509926 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549927 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9928
9929 std::string response_data;
9930 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9931 EXPECT_EQ("hello world", response_data);
9932
9933 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:239934 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:409935 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539936 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279937 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269938 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389939
[email protected]90499482013-06-01 00:39:509940 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549941
[email protected]49639fa2011-12-20 23:22:419942 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549943 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419944 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549945
9946 response = trans->GetResponseInfo();
9947 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509948 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549949 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539950 EXPECT_TRUE(response->was_fetched_via_spdy);
9951 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549952
9953 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9954 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429955}
9956
[email protected]044de0642010-06-17 10:42:159957// GenerateAuthToken is a mighty big test.
9958// It tests all permutation of GenerateAuthToken behavior:
9959// - Synchronous and Asynchronous completion.
9960// - OK or error on completion.
9961// - Direct connection, non-authenticating proxy, and authenticating proxy.
9962// - HTTP or HTTPS backend (to include proxy tunneling).
9963// - Non-authenticating and authenticating backend.
9964//
[email protected]fe3b7dc2012-02-03 19:52:099965// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159966// problems generating an auth token for an authenticating proxy, we don't
9967// need to test all permutations of the backend server).
9968//
9969// The test proceeds by going over each of the configuration cases, and
9970// potentially running up to three rounds in each of the tests. The TestConfig
9971// specifies both the configuration for the test as well as the expectations
9972// for the results.
[email protected]23e482282013-06-14 16:08:029973TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509974 static const char kServer[] = "http://www.example.com";
9975 static const char kSecureServer[] = "https://www.example.com";
9976 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159977 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9978
9979 enum AuthTiming {
9980 AUTH_NONE,
9981 AUTH_SYNC,
9982 AUTH_ASYNC,
9983 };
9984
9985 const MockWrite kGet(
9986 "GET / HTTP/1.1\r\n"
9987 "Host: www.example.com\r\n"
9988 "Connection: keep-alive\r\n\r\n");
9989 const MockWrite kGetProxy(
9990 "GET http://www.example.com/ HTTP/1.1\r\n"
9991 "Host: www.example.com\r\n"
9992 "Proxy-Connection: keep-alive\r\n\r\n");
9993 const MockWrite kGetAuth(
9994 "GET / HTTP/1.1\r\n"
9995 "Host: www.example.com\r\n"
9996 "Connection: keep-alive\r\n"
9997 "Authorization: auth_token\r\n\r\n");
9998 const MockWrite kGetProxyAuth(
9999 "GET http://www.example.com/ HTTP/1.1\r\n"
10000 "Host: www.example.com\r\n"
10001 "Proxy-Connection: keep-alive\r\n"
10002 "Proxy-Authorization: auth_token\r\n\r\n");
10003 const MockWrite kGetAuthThroughProxy(
10004 "GET http://www.example.com/ HTTP/1.1\r\n"
10005 "Host: www.example.com\r\n"
10006 "Proxy-Connection: keep-alive\r\n"
10007 "Authorization: auth_token\r\n\r\n");
10008 const MockWrite kGetAuthWithProxyAuth(
10009 "GET http://www.example.com/ HTTP/1.1\r\n"
10010 "Host: www.example.com\r\n"
10011 "Proxy-Connection: keep-alive\r\n"
10012 "Proxy-Authorization: auth_token\r\n"
10013 "Authorization: auth_token\r\n\r\n");
10014 const MockWrite kConnect(
10015 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10016 "Host: www.example.com\r\n"
10017 "Proxy-Connection: keep-alive\r\n\r\n");
10018 const MockWrite kConnectProxyAuth(
10019 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10020 "Host: www.example.com\r\n"
10021 "Proxy-Connection: keep-alive\r\n"
10022 "Proxy-Authorization: auth_token\r\n\r\n");
10023
10024 const MockRead kSuccess(
10025 "HTTP/1.1 200 OK\r\n"
10026 "Content-Type: text/html; charset=iso-8859-1\r\n"
10027 "Content-Length: 3\r\n\r\n"
10028 "Yes");
10029 const MockRead kFailure(
10030 "Should not be called.");
10031 const MockRead kServerChallenge(
10032 "HTTP/1.1 401 Unauthorized\r\n"
10033 "WWW-Authenticate: Mock realm=server\r\n"
10034 "Content-Type: text/html; charset=iso-8859-1\r\n"
10035 "Content-Length: 14\r\n\r\n"
10036 "Unauthorized\r\n");
10037 const MockRead kProxyChallenge(
10038 "HTTP/1.1 407 Unauthorized\r\n"
10039 "Proxy-Authenticate: Mock realm=proxy\r\n"
10040 "Proxy-Connection: close\r\n"
10041 "Content-Type: text/html; charset=iso-8859-1\r\n"
10042 "Content-Length: 14\r\n\r\n"
10043 "Unauthorized\r\n");
10044 const MockRead kProxyConnected(
10045 "HTTP/1.1 200 Connection Established\r\n\r\n");
10046
10047 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
10048 // no constructors, but the C++ compiler on Windows warns about
10049 // unspecified data in compound literals. So, moved to using constructors,
10050 // and TestRound's created with the default constructor should not be used.
10051 struct TestRound {
10052 TestRound()
10053 : expected_rv(ERR_UNEXPECTED),
10054 extra_write(NULL),
10055 extra_read(NULL) {
10056 }
10057 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10058 int expected_rv_arg)
10059 : write(write_arg),
10060 read(read_arg),
10061 expected_rv(expected_rv_arg),
10062 extra_write(NULL),
10063 extra_read(NULL) {
10064 }
10065 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10066 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0110067 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1510068 : write(write_arg),
10069 read(read_arg),
10070 expected_rv(expected_rv_arg),
10071 extra_write(extra_write_arg),
10072 extra_read(extra_read_arg) {
10073 }
10074 MockWrite write;
10075 MockRead read;
10076 int expected_rv;
10077 const MockWrite* extra_write;
10078 const MockRead* extra_read;
10079 };
10080
10081 static const int kNoSSL = 500;
10082
10083 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5110084 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1510085 AuthTiming proxy_auth_timing;
10086 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5110087 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1510088 AuthTiming server_auth_timing;
10089 int server_auth_rv;
10090 int num_auth_rounds;
10091 int first_ssl_round;
10092 TestRound rounds[3];
10093 } test_configs[] = {
10094 // Non-authenticating HTTP server with a direct connection.
10095 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10096 { TestRound(kGet, kSuccess, OK)}},
10097 // Authenticating HTTP server with a direct connection.
10098 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10099 { TestRound(kGet, kServerChallenge, OK),
10100 TestRound(kGetAuth, kSuccess, OK)}},
10101 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10102 { TestRound(kGet, kServerChallenge, OK),
10103 TestRound(kGetAuth, kFailure, kAuthErr)}},
10104 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10105 { TestRound(kGet, kServerChallenge, OK),
10106 TestRound(kGetAuth, kSuccess, OK)}},
10107 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10108 { TestRound(kGet, kServerChallenge, OK),
10109 TestRound(kGetAuth, kFailure, kAuthErr)}},
10110 // Non-authenticating HTTP server through a non-authenticating proxy.
10111 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10112 { TestRound(kGetProxy, kSuccess, OK)}},
10113 // Authenticating HTTP server through a non-authenticating proxy.
10114 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10115 { TestRound(kGetProxy, kServerChallenge, OK),
10116 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10117 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10118 { TestRound(kGetProxy, kServerChallenge, OK),
10119 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10120 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10121 { TestRound(kGetProxy, kServerChallenge, OK),
10122 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10123 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10124 { TestRound(kGetProxy, kServerChallenge, OK),
10125 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10126 // Non-authenticating HTTP server through an authenticating proxy.
10127 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10128 { TestRound(kGetProxy, kProxyChallenge, OK),
10129 TestRound(kGetProxyAuth, kSuccess, OK)}},
10130 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10131 { TestRound(kGetProxy, kProxyChallenge, OK),
10132 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10133 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10134 { TestRound(kGetProxy, kProxyChallenge, OK),
10135 TestRound(kGetProxyAuth, kSuccess, OK)}},
10136 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10137 { TestRound(kGetProxy, kProxyChallenge, OK),
10138 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10139 // Authenticating HTTP server through an authenticating proxy.
10140 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10141 { TestRound(kGetProxy, kProxyChallenge, OK),
10142 TestRound(kGetProxyAuth, kServerChallenge, OK),
10143 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10144 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10145 { TestRound(kGetProxy, kProxyChallenge, OK),
10146 TestRound(kGetProxyAuth, kServerChallenge, OK),
10147 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10148 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10149 { TestRound(kGetProxy, kProxyChallenge, OK),
10150 TestRound(kGetProxyAuth, kServerChallenge, OK),
10151 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10152 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10153 { TestRound(kGetProxy, kProxyChallenge, OK),
10154 TestRound(kGetProxyAuth, kServerChallenge, OK),
10155 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10156 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10157 { TestRound(kGetProxy, kProxyChallenge, OK),
10158 TestRound(kGetProxyAuth, kServerChallenge, OK),
10159 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10160 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10161 { TestRound(kGetProxy, kProxyChallenge, OK),
10162 TestRound(kGetProxyAuth, kServerChallenge, OK),
10163 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10164 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10165 { TestRound(kGetProxy, kProxyChallenge, OK),
10166 TestRound(kGetProxyAuth, kServerChallenge, OK),
10167 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10168 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10169 { TestRound(kGetProxy, kProxyChallenge, OK),
10170 TestRound(kGetProxyAuth, kServerChallenge, OK),
10171 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10172 // Non-authenticating HTTPS server with a direct connection.
10173 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10174 { TestRound(kGet, kSuccess, OK)}},
10175 // Authenticating HTTPS server with a direct connection.
10176 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10177 { TestRound(kGet, kServerChallenge, OK),
10178 TestRound(kGetAuth, kSuccess, OK)}},
10179 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10180 { TestRound(kGet, kServerChallenge, OK),
10181 TestRound(kGetAuth, kFailure, kAuthErr)}},
10182 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10183 { TestRound(kGet, kServerChallenge, OK),
10184 TestRound(kGetAuth, kSuccess, OK)}},
10185 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10186 { TestRound(kGet, kServerChallenge, OK),
10187 TestRound(kGetAuth, kFailure, kAuthErr)}},
10188 // Non-authenticating HTTPS server with a non-authenticating proxy.
10189 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10190 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
10191 // Authenticating HTTPS server through a non-authenticating proxy.
10192 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10193 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10194 TestRound(kGetAuth, kSuccess, OK)}},
10195 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10196 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10197 TestRound(kGetAuth, kFailure, kAuthErr)}},
10198 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10199 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10200 TestRound(kGetAuth, kSuccess, OK)}},
10201 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10202 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10203 TestRound(kGetAuth, kFailure, kAuthErr)}},
10204 // Non-Authenticating HTTPS server through an authenticating proxy.
10205 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10206 { TestRound(kConnect, kProxyChallenge, OK),
10207 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10208 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10209 { TestRound(kConnect, kProxyChallenge, OK),
10210 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10211 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10212 { TestRound(kConnect, kProxyChallenge, OK),
10213 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10214 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10215 { TestRound(kConnect, kProxyChallenge, OK),
10216 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10217 // Authenticating HTTPS server through an authenticating proxy.
10218 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10219 { TestRound(kConnect, kProxyChallenge, OK),
10220 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10221 &kGet, &kServerChallenge),
10222 TestRound(kGetAuth, kSuccess, OK)}},
10223 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10224 { TestRound(kConnect, kProxyChallenge, OK),
10225 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10226 &kGet, &kServerChallenge),
10227 TestRound(kGetAuth, kFailure, kAuthErr)}},
10228 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10229 { TestRound(kConnect, kProxyChallenge, OK),
10230 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10231 &kGet, &kServerChallenge),
10232 TestRound(kGetAuth, kSuccess, OK)}},
10233 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10234 { TestRound(kConnect, kProxyChallenge, OK),
10235 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10236 &kGet, &kServerChallenge),
10237 TestRound(kGetAuth, kFailure, kAuthErr)}},
10238 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10239 { TestRound(kConnect, kProxyChallenge, OK),
10240 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10241 &kGet, &kServerChallenge),
10242 TestRound(kGetAuth, kSuccess, OK)}},
10243 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10244 { TestRound(kConnect, kProxyChallenge, OK),
10245 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10246 &kGet, &kServerChallenge),
10247 TestRound(kGetAuth, kFailure, kAuthErr)}},
10248 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10249 { TestRound(kConnect, kProxyChallenge, OK),
10250 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10251 &kGet, &kServerChallenge),
10252 TestRound(kGetAuth, kSuccess, OK)}},
10253 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10254 { TestRound(kConnect, kProxyChallenge, OK),
10255 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10256 &kGet, &kServerChallenge),
10257 TestRound(kGetAuth, kFailure, kAuthErr)}},
10258 };
10259
viettrungluue4a8b882014-10-16 06:17:3810260 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810261 HttpAuthHandlerMock::Factory* auth_factory(
10262 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710263 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510264 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610265
10266 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510267 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810268 for (int n = 0; n < 2; n++) {
10269 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10270 std::string auth_challenge = "Mock realm=proxy";
10271 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410272 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10273 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810274 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10275 origin, BoundNetLog());
10276 auth_handler->SetGenerateExpectation(
10277 test_config.proxy_auth_timing == AUTH_ASYNC,
10278 test_config.proxy_auth_rv);
10279 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10280 }
[email protected]044de0642010-06-17 10:42:1510281 }
10282 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010283 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510284 std::string auth_challenge = "Mock realm=server";
10285 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410286 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10287 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510288 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10289 origin, BoundNetLog());
10290 auth_handler->SetGenerateExpectation(
10291 test_config.server_auth_timing == AUTH_ASYNC,
10292 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810293 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510294 }
10295 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:0710296 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:1210297 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:1510298 } else {
[email protected]bb88e1d32013-05-03 23:11:0710299 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:1510300 }
10301
10302 HttpRequestInfo request;
10303 request.method = "GET";
10304 request.url = GURL(test_config.server_url);
10305 request.load_flags = 0;
10306
[email protected]bb88e1d32013-05-03 23:11:0710307 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110308 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510309
rchcb68dc62015-05-21 04:45:3610310 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
10311
10312 std::vector<std::vector<MockRead>> mock_reads(1);
10313 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1510314 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10315 const TestRound& read_write_round = test_config.rounds[round];
10316
10317 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3610318 mock_reads.back().push_back(read_write_round.read);
10319 mock_writes.back().push_back(read_write_round.write);
10320
10321 // kProxyChallenge uses Proxy-Connection: close which means that the
10322 // socket is closed and a new one will be created for the next request.
10323 if (read_write_round.read.data == kProxyChallenge.data &&
10324 read_write_round.write.data != kConnect.data) {
10325 mock_reads.push_back(std::vector<MockRead>());
10326 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1510327 }
10328
rchcb68dc62015-05-21 04:45:3610329 if (read_write_round.extra_read) {
10330 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1510331 }
rchcb68dc62015-05-21 04:45:3610332 if (read_write_round.extra_write) {
10333 mock_writes.back().push_back(*read_write_round.extra_write);
10334 }
[email protected]044de0642010-06-17 10:42:1510335
10336 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1510337 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710338 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510339 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3610340 }
[email protected]044de0642010-06-17 10:42:1510341
rchcb68dc62015-05-21 04:45:3610342 ScopedVector<StaticSocketDataProvider> data_providers;
10343 for (size_t i = 0; i < mock_reads.size(); ++i) {
10344 data_providers.push_back(new StaticSocketDataProvider(
10345 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
10346 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
10347 session_deps_.socket_factory->AddSocketDataProvider(
10348 data_providers.back());
10349 }
10350
10351 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10352 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1510353 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110354 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510355 int rv;
10356 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110357 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510358 } else {
[email protected]49639fa2011-12-20 23:22:4110359 rv = trans.RestartWithAuth(
10360 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510361 }
10362 if (rv == ERR_IO_PENDING)
10363 rv = callback.WaitForResult();
10364
10365 // Compare results with expected data.
10366 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010367 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5510368 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1510369 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10370 continue;
10371 }
10372 if (round + 1 < test_config.num_auth_rounds) {
10373 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10374 } else {
10375 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10376 }
10377 }
[email protected]e5ae96a2010-04-14 20:12:4510378 }
10379}
10380
[email protected]23e482282013-06-14 16:08:0210381TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410382 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410383 HttpAuthHandlerMock::Factory* auth_factory(
10384 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710385 session_deps_.http_auth_handler_factory.reset(auth_factory);
10386 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10387 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10388 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410389
10390 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10391 auth_handler->set_connection_based(true);
10392 std::string auth_challenge = "Mock realm=server";
10393 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410394 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10395 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410396 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10397 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810398 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410399
[email protected]c871bce92010-07-15 21:51:1410400 int rv = OK;
10401 const HttpResponseInfo* response = NULL;
10402 HttpRequestInfo request;
10403 request.method = "GET";
10404 request.url = origin;
10405 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710406
[email protected]bb88e1d32013-05-03 23:11:0710407 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010408
10409 // Use a TCP Socket Pool with only one connection per group. This is used
10410 // to validate that the TCP socket is not released to the pool between
10411 // each round of multi-round authentication.
10412 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810413 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010414 50, // Max sockets for pool
10415 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710416 session_deps_.host_resolver.get(),
10417 session_deps_.socket_factory.get(),
10418 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410419 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10420 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210421 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110422 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010423
[email protected]262eec82013-03-19 21:01:3610424 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010425 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110426 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410427
10428 const MockWrite kGet(
10429 "GET / HTTP/1.1\r\n"
10430 "Host: www.example.com\r\n"
10431 "Connection: keep-alive\r\n\r\n");
10432 const MockWrite kGetAuth(
10433 "GET / HTTP/1.1\r\n"
10434 "Host: www.example.com\r\n"
10435 "Connection: keep-alive\r\n"
10436 "Authorization: auth_token\r\n\r\n");
10437
10438 const MockRead kServerChallenge(
10439 "HTTP/1.1 401 Unauthorized\r\n"
10440 "WWW-Authenticate: Mock realm=server\r\n"
10441 "Content-Type: text/html; charset=iso-8859-1\r\n"
10442 "Content-Length: 14\r\n\r\n"
10443 "Unauthorized\r\n");
10444 const MockRead kSuccess(
10445 "HTTP/1.1 200 OK\r\n"
10446 "Content-Type: text/html; charset=iso-8859-1\r\n"
10447 "Content-Length: 3\r\n\r\n"
10448 "Yes");
10449
10450 MockWrite writes[] = {
10451 // First round
10452 kGet,
10453 // Second round
10454 kGetAuth,
10455 // Third round
10456 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010457 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010458 kGetAuth,
10459 // Competing request
10460 kGet,
[email protected]c871bce92010-07-15 21:51:1410461 };
10462 MockRead reads[] = {
10463 // First round
10464 kServerChallenge,
10465 // Second round
10466 kServerChallenge,
10467 // Third round
[email protected]eca50e122010-09-11 14:03:3010468 kServerChallenge,
10469 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410470 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010471 // Competing response
10472 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410473 };
10474 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10475 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710476 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410477
thestig9d3bb0c2015-01-24 00:49:5110478 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010479
10480 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410481 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110482 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410483 if (rv == ERR_IO_PENDING)
10484 rv = callback.WaitForResult();
10485 EXPECT_EQ(OK, rv);
10486 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010487 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410488 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810489 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410490
[email protected]7ef4cbbb2011-02-06 11:19:1010491 // In between rounds, another request comes in for the same domain.
10492 // It should not be able to grab the TCP socket that trans has already
10493 // claimed.
10494 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010495 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110496 TestCompletionCallback callback_compete;
10497 rv = trans_compete->Start(
10498 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010499 EXPECT_EQ(ERR_IO_PENDING, rv);
10500 // callback_compete.WaitForResult at this point would stall forever,
10501 // since the HttpNetworkTransaction does not release the request back to
10502 // the pool until after authentication completes.
10503
10504 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410505 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110506 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410507 if (rv == ERR_IO_PENDING)
10508 rv = callback.WaitForResult();
10509 EXPECT_EQ(OK, rv);
10510 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010511 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410512 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810513 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410514
[email protected]7ef4cbbb2011-02-06 11:19:1010515 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410516 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110517 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410518 if (rv == ERR_IO_PENDING)
10519 rv = callback.WaitForResult();
10520 EXPECT_EQ(OK, rv);
10521 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010522 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410523 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810524 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010525
[email protected]7ef4cbbb2011-02-06 11:19:1010526 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010527 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110528 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010529 if (rv == ERR_IO_PENDING)
10530 rv = callback.WaitForResult();
10531 EXPECT_EQ(OK, rv);
10532 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010533 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010534 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810535 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010536
10537 // Read the body since the fourth round was successful. This will also
10538 // release the socket back to the pool.
10539 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010540 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010541 if (rv == ERR_IO_PENDING)
10542 rv = callback.WaitForResult();
10543 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010544 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010545 EXPECT_EQ(0, rv);
10546 // There are still 0 idle sockets, since the trans_compete transaction
10547 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810548 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010549
10550 // The competing request can now finish. Wait for the headers and then
10551 // read the body.
10552 rv = callback_compete.WaitForResult();
10553 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010554 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010555 if (rv == ERR_IO_PENDING)
10556 rv = callback.WaitForResult();
10557 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010558 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010559 EXPECT_EQ(0, rv);
10560
10561 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810562 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410563}
10564
[email protected]65041fa2010-05-21 06:56:5310565// This tests the case that a request is issued via http instead of spdy after
10566// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210567TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:2310568 session_deps_.use_alternate_protocols = true;
10569 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610570 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310571 session_deps_.next_protos = next_protos;
10572
[email protected]65041fa2010-05-21 06:56:5310573 HttpRequestInfo request;
10574 request.method = "GET";
bncce36dca22015-04-21 22:11:2310575 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310576 request.load_flags = 0;
10577
10578 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310579 MockWrite(
10580 "GET / HTTP/1.1\r\n"
10581 "Host: www.example.org\r\n"
10582 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310583 };
10584
[email protected]8a0fc822013-06-27 20:52:4310585 std::string alternate_protocol_http_header =
10586 GetAlternateProtocolHttpHeader();
10587
[email protected]65041fa2010-05-21 06:56:5310588 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210589 MockRead("HTTP/1.1 200 OK\r\n"),
10590 MockRead(alternate_protocol_http_header.c_str()),
10591 MockRead("\r\n"),
10592 MockRead("hello world"),
10593 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310594 };
10595
[email protected]8ddf8322012-02-23 18:08:0610596 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810597 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310598
[email protected]bb88e1d32013-05-03 23:11:0710599 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310600
10601 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10602 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710603 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310604
[email protected]49639fa2011-12-20 23:22:4110605 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310606
[email protected]bb88e1d32013-05-03 23:11:0710607 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610608 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310610
[email protected]49639fa2011-12-20 23:22:4110611 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310612
10613 EXPECT_EQ(ERR_IO_PENDING, rv);
10614 EXPECT_EQ(OK, callback.WaitForResult());
10615
10616 const HttpResponseInfo* response = trans->GetResponseInfo();
10617 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010618 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310619 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10620
10621 std::string response_data;
10622 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10623 EXPECT_EQ("hello world", response_data);
10624
10625 EXPECT_FALSE(response->was_fetched_via_spdy);
10626 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310627}
[email protected]26ef6582010-06-24 02:30:4710628
[email protected]23e482282013-06-14 16:08:0210629TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710630 // Simulate the SSL handshake completing with an NPN negotiation
10631 // followed by an immediate server closing of the socket.
10632 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310633 session_deps_.use_alternate_protocols = true;
10634 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710635
10636 HttpRequestInfo request;
10637 request.method = "GET";
bncce36dca22015-04-21 22:11:2310638 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710639 request.load_flags = 0;
10640
[email protected]8ddf8322012-02-23 18:08:0610641 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210642 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710643 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710644
[email protected]cdf8f7e72013-05-23 10:56:4610645 scoped_ptr<SpdyFrame> req(
10646 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310647 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710648
10649 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610650 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710651 };
10652
rch8e6c6c42015-05-01 14:05:1310653 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10654 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710655 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710656
[email protected]49639fa2011-12-20 23:22:4110657 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710658
[email protected]bb88e1d32013-05-03 23:11:0710659 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610660 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010661 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710662
[email protected]49639fa2011-12-20 23:22:4110663 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710664 EXPECT_EQ(ERR_IO_PENDING, rv);
10665 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710666}
[email protected]65d34382010-07-01 18:12:2610667
[email protected]795cbf82013-07-22 09:37:2710668// A subclass of HttpAuthHandlerMock that records the request URL when
10669// it gets it. This is needed since the auth handler may get destroyed
10670// before we get a chance to query it.
10671class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10672 public:
10673 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10674
dchengb03027d2014-10-21 12:00:2010675 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710676
10677 protected:
dchengb03027d2014-10-21 12:00:2010678 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10679 const HttpRequestInfo* request,
10680 const CompletionCallback& callback,
10681 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710682 *url_ = request->url;
10683 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10684 credentials, request, callback, auth_token);
10685 }
10686
10687 private:
10688 GURL* url_;
10689};
10690
[email protected]23e482282013-06-14 16:08:0210691TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010692 // This test ensures that the URL passed into the proxy is upgraded
10693 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310694 session_deps_.use_alternate_protocols = true;
10695 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010696
[email protected]bb88e1d32013-05-03 23:11:0710697 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010698 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110699 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710700 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710701 GURL request_url;
10702 {
10703 HttpAuthHandlerMock::Factory* auth_factory =
10704 new HttpAuthHandlerMock::Factory();
10705 UrlRecordingHttpAuthHandlerMock* auth_handler =
10706 new UrlRecordingHttpAuthHandlerMock(&request_url);
10707 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10708 auth_factory->set_do_init_from_challenge(true);
10709 session_deps_.http_auth_handler_factory.reset(auth_factory);
10710 }
[email protected]f45c1ee2010-08-03 00:54:3010711
10712 HttpRequestInfo request;
10713 request.method = "GET";
bncce36dca22015-04-21 22:11:2310714 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3010715 request.load_flags = 0;
10716
10717 // First round goes unauthenticated through the proxy.
10718 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2310719 MockWrite(
10720 "GET http://www.example.org/ HTTP/1.1\r\n"
10721 "Host: www.example.org\r\n"
10722 "Proxy-Connection: keep-alive\r\n"
10723 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010724 };
10725 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610726 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810727 MockRead("HTTP/1.1 200 OK\r\n"),
10728 MockRead("Alternate-Protocol: 443:"),
10729 MockRead(GetAlternateProtocolFromParam()),
10730 MockRead("\r\n"),
10731 MockRead("Proxy-Connection: close\r\n"),
10732 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010733 };
10734 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10735 data_writes_1, arraysize(data_writes_1));
10736
bncce36dca22015-04-21 22:11:2310737 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3010738 // Alternate-Protocol announcement in the first round. It fails due
10739 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2310740 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5910741 // Proxy-Authorization headers. There is then a SPDY request round.
10742 //
[email protected]fe3b7dc2012-02-03 19:52:0910743 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10744 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10745 // does a Disconnect and Connect on the same socket, rather than trying
10746 // to obtain a new one.
10747 //
[email protected]394816e92010-08-03 07:38:5910748 // NOTE: Originally, the proxy response to the second CONNECT request
10749 // simply returned another 407 so the unit test could skip the SSL connection
10750 // establishment and SPDY framing issues. Alas, the
10751 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010752 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910753
[email protected]cdf8f7e72013-05-23 10:56:4610754 scoped_ptr<SpdyFrame> req(
10755 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210756 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10757 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010758
[email protected]394816e92010-08-03 07:38:5910759 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2310760 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310761 MockWrite(ASYNC, 0,
10762 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10763 "Host: www.example.org\r\n"
10764 "Proxy-Connection: keep-alive\r\n"
10765 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910766
bncce36dca22015-04-21 22:11:2310767 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310768 MockWrite(ASYNC, 2,
10769 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10770 "Host: www.example.org\r\n"
10771 "Proxy-Connection: keep-alive\r\n"
10772 "Proxy-Authorization: auth_token\r\n"
10773 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010774
bncce36dca22015-04-21 22:11:2310775 // SPDY request
rch8e6c6c42015-05-01 14:05:1310776 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3010777 };
[email protected]394816e92010-08-03 07:38:5910778 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10779 "Proxy-Authenticate: Mock\r\n"
10780 "Proxy-Connection: close\r\n"
10781 "\r\n");
10782 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10783 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1310784 // First connection attempt fails
10785 MockRead(ASYNC, kRejectConnectResponse,
10786 arraysize(kRejectConnectResponse) - 1, 1),
[email protected]394816e92010-08-03 07:38:5910787
rch8e6c6c42015-05-01 14:05:1310788 // Second connection attempt passes
10789 MockRead(ASYNC, kAcceptConnectResponse,
10790 arraysize(kAcceptConnectResponse) - 1, 3),
[email protected]394816e92010-08-03 07:38:5910791
rch8e6c6c42015-05-01 14:05:1310792 // SPDY response
10793 CreateMockRead(*resp.get(), 5),
10794 CreateMockRead(*data.get(), 6),
10795 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5910796 };
rch8e6c6c42015-05-01 14:05:1310797 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
10798 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010799
[email protected]8ddf8322012-02-23 18:08:0610800 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210801 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310802 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10803 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3010804
[email protected]d973e99a2012-02-17 21:02:3610805 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510806 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10807 NULL, 0, NULL, 0);
10808 hanging_non_alternate_protocol_socket.set_connect_data(
10809 never_finishing_connect);
10810
[email protected]bb88e1d32013-05-03 23:11:0710811 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10812 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10813 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10814 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510815 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710816 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010817
10818 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110819 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610820 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010821 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110822 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010823 EXPECT_EQ(ERR_IO_PENDING, rv);
10824 EXPECT_EQ(OK, callback_1.WaitForResult());
10825
10826 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110827 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610828 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010829 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110830 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010831 EXPECT_EQ(ERR_IO_PENDING, rv);
10832 EXPECT_EQ(OK, callback_2.WaitForResult());
10833 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010834 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010835 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10836
10837 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110838 TestCompletionCallback callback_3;
10839 rv = trans_2->RestartWithAuth(
10840 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010841 EXPECT_EQ(ERR_IO_PENDING, rv);
10842 EXPECT_EQ(OK, callback_3.WaitForResult());
10843
10844 // After all that work, these two lines (or actually, just the scheme) are
10845 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010846 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2310847 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3010848
[email protected]029c83b62013-01-24 05:28:2010849 LoadTimingInfo load_timing_info;
10850 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10851 TestLoadTimingNotReusedWithPac(load_timing_info,
10852 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810853}
10854
10855// Test that if we cancel the transaction as the connection is completing, that
10856// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210857TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810858 // Setup everything about the connection to complete synchronously, so that
10859 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10860 // for is the callback from the HttpStreamRequest.
10861 // Then cancel the transaction.
10862 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610863 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810864 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610865 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10866 MockRead(SYNCHRONOUS, "hello world"),
10867 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810868 };
10869
[email protected]8e6441ca2010-08-19 05:56:3810870 HttpRequestInfo request;
10871 request.method = "GET";
bncce36dca22015-04-21 22:11:2310872 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3810873 request.load_flags = 0;
10874
[email protected]bb88e1d32013-05-03 23:11:0710875 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710876 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710877 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4110878 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2710879
[email protected]8e6441ca2010-08-19 05:56:3810880 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10881 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710882 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810883
[email protected]49639fa2011-12-20 23:22:4110884 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810885
vishal.b62985ca92015-04-17 08:45:5110886 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4110887 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810888 EXPECT_EQ(ERR_IO_PENDING, rv);
10889 trans.reset(); // Cancel the transaction here.
10890
[email protected]2da659e2013-05-23 20:51:3410891 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010892}
10893
[email protected]ecab6e052014-05-16 14:58:1210894// Test that if a transaction is cancelled after receiving the headers, the
10895// stream is drained properly and added back to the socket pool. The main
10896// purpose of this test is to make sure that an HttpStreamParser can be read
10897// from after the HttpNetworkTransaction and the objects it owns have been
10898// deleted.
10899// See http://crbug.com/368418
10900TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10901 MockRead data_reads[] = {
10902 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10903 MockRead(ASYNC, "Content-Length: 2\r\n"),
10904 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10905 MockRead(ASYNC, "1"),
10906 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10907 // HttpNetworkTransaction has been deleted.
10908 MockRead(ASYNC, "2"),
10909 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10910 };
10911 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10912 session_deps_.socket_factory->AddSocketDataProvider(&data);
10913
10914 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10915
10916 {
10917 HttpRequestInfo request;
10918 request.method = "GET";
bncce36dca22015-04-21 22:11:2310919 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1210920 request.load_flags = 0;
10921
dcheng48459ac22014-08-26 00:46:4110922 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1210923 TestCompletionCallback callback;
10924
10925 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10926 EXPECT_EQ(ERR_IO_PENDING, rv);
10927 callback.WaitForResult();
10928
10929 const HttpResponseInfo* response = trans.GetResponseInfo();
10930 ASSERT_TRUE(response != NULL);
10931 EXPECT_TRUE(response->headers.get() != NULL);
10932 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10933
10934 // The transaction and HttpRequestInfo are deleted.
10935 }
10936
10937 // Let the HttpResponseBodyDrainer drain the socket.
10938 base::MessageLoop::current()->RunUntilIdle();
10939
10940 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4110941 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1210942}
10943
[email protected]76a505b2010-08-25 06:23:0010944// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210945TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710946 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010947 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110948 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710949 session_deps_.net_log = log.bound().net_log();
10950 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010951
[email protected]76a505b2010-08-25 06:23:0010952 HttpRequestInfo request;
10953 request.method = "GET";
bncce36dca22015-04-21 22:11:2310954 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010955
10956 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310957 MockWrite(
10958 "GET http://www.example.org/ HTTP/1.1\r\n"
10959 "Host: www.example.org\r\n"
10960 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010961 };
10962
10963 MockRead data_reads1[] = {
10964 MockRead("HTTP/1.1 200 OK\r\n"),
10965 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10966 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610967 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010968 };
10969
10970 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10971 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710972 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010973
[email protected]49639fa2011-12-20 23:22:4110974 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010975
[email protected]262eec82013-03-19 21:01:3610976 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010977 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710978 BeforeProxyHeadersSentHandler proxy_headers_handler;
10979 trans->SetBeforeProxyHeadersSentCallback(
10980 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10981 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010982
[email protected]49639fa2011-12-20 23:22:4110983 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010984 EXPECT_EQ(ERR_IO_PENDING, rv);
10985
10986 rv = callback1.WaitForResult();
10987 EXPECT_EQ(OK, rv);
10988
10989 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010990 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010991
10992 EXPECT_TRUE(response->headers->IsKeepAlive());
10993 EXPECT_EQ(200, response->headers->response_code());
10994 EXPECT_EQ(100, response->headers->GetContentLength());
10995 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510996 EXPECT_TRUE(
10997 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710998 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10999 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0011000 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2011001
11002 LoadTimingInfo load_timing_info;
11003 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11004 TestLoadTimingNotReusedWithPac(load_timing_info,
11005 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0011006}
11007
11008// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211009TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0711010 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2011011 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5111012 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711013 session_deps_.net_log = log.bound().net_log();
11014 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011015
[email protected]76a505b2010-08-25 06:23:0011016 HttpRequestInfo request;
11017 request.method = "GET";
bncce36dca22015-04-21 22:11:2311018 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011019
11020 // Since we have proxy, should try to establish tunnel.
11021 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311022 MockWrite(
11023 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11024 "Host: www.example.org\r\n"
11025 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011026
bncce36dca22015-04-21 22:11:2311027 MockWrite(
11028 "GET / HTTP/1.1\r\n"
11029 "Host: www.example.org\r\n"
11030 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011031 };
11032
11033 MockRead data_reads1[] = {
11034 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
11035
11036 MockRead("HTTP/1.1 200 OK\r\n"),
11037 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11038 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611039 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011040 };
11041
11042 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11043 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711044 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611045 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711046 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011047
[email protected]49639fa2011-12-20 23:22:4111048 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011049
[email protected]262eec82013-03-19 21:01:3611050 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011051 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011052
[email protected]49639fa2011-12-20 23:22:4111053 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011054 EXPECT_EQ(ERR_IO_PENDING, rv);
11055
11056 rv = callback1.WaitForResult();
11057 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4611058 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011059 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011060 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011061 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011062 NetLog::PHASE_NONE);
11063 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011064 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011065 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11066 NetLog::PHASE_NONE);
11067
11068 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011069 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011070
11071 EXPECT_TRUE(response->headers->IsKeepAlive());
11072 EXPECT_EQ(200, response->headers->response_code());
11073 EXPECT_EQ(100, response->headers->GetContentLength());
11074 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11075 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511076 EXPECT_TRUE(
11077 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2011078
11079 LoadTimingInfo load_timing_info;
11080 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11081 TestLoadTimingNotReusedWithPac(load_timing_info,
11082 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0011083}
11084
11085// Test a basic HTTPS GET request through a proxy, but the server hangs up
11086// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0211087TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0711088 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5111089 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711090 session_deps_.net_log = log.bound().net_log();
11091 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011092
[email protected]76a505b2010-08-25 06:23:0011093 HttpRequestInfo request;
11094 request.method = "GET";
bncce36dca22015-04-21 22:11:2311095 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011096
11097 // Since we have proxy, should try to establish tunnel.
11098 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311099 MockWrite(
11100 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11101 "Host: www.example.org\r\n"
11102 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011103
bncce36dca22015-04-21 22:11:2311104 MockWrite(
11105 "GET / HTTP/1.1\r\n"
11106 "Host: www.example.org\r\n"
11107 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011108 };
11109
11110 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0611111 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0011112 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611113 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0011114 };
11115
11116 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11117 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711118 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611119 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711120 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011121
[email protected]49639fa2011-12-20 23:22:4111122 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011123
[email protected]262eec82013-03-19 21:01:3611124 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011125 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011126
[email protected]49639fa2011-12-20 23:22:4111127 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011128 EXPECT_EQ(ERR_IO_PENDING, rv);
11129
11130 rv = callback1.WaitForResult();
11131 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4611132 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011133 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011134 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011135 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011136 NetLog::PHASE_NONE);
11137 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011138 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011139 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11140 NetLog::PHASE_NONE);
11141}
11142
[email protected]749eefa82010-09-13 22:14:0311143// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0211144TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4611145 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2311146 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1311147 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0311148
[email protected]23e482282013-06-14 16:08:0211149 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11150 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0311151 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311152 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0311153 };
11154
rch8e6c6c42015-05-01 14:05:1311155 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11156 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711157 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0311158
[email protected]8ddf8322012-02-23 18:08:0611159 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211160 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711161 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0311162
[email protected]bb88e1d32013-05-03 23:11:0711163 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0311164
11165 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2311166 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011167 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311168 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711169 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2611170 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311171
11172 HttpRequestInfo request;
11173 request.method = "GET";
bncce36dca22015-04-21 22:11:2311174 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0311175 request.load_flags = 0;
11176
11177 // This is the important line that marks this as a preconnect.
11178 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
11179
[email protected]262eec82013-03-19 21:01:3611180 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011181 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0311182
[email protected]41d64e82013-07-03 22:44:2611183 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4111184 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311185 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111186 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0311187}
11188
[email protected]73b8dd222010-11-11 19:55:2411189// Given a net error, cause that error to be returned from the first Write()
11190// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0211191void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0711192 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2911193 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711194 request_info.url = GURL("https://www.example.com/");
11195 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911196 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711197
[email protected]8ddf8322012-02-23 18:08:0611198 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2911199 MockWrite data_writes[] = {
11200 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2411201 };
ttuttle859dc7a2015-04-23 19:42:2911202 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711203 session_deps_.socket_factory->AddSocketDataProvider(&data);
11204 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2411205
[email protected]bb88e1d32013-05-03 23:11:0711206 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611207 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011208 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2411209
[email protected]49639fa2011-12-20 23:22:4111210 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911211 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11212 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2411213 rv = callback.WaitForResult();
11214 ASSERT_EQ(error, rv);
11215}
11216
[email protected]23e482282013-06-14 16:08:0211217TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411218 // Just check a grab bag of cert errors.
11219 static const int kErrors[] = {
11220 ERR_CERT_COMMON_NAME_INVALID,
11221 ERR_CERT_AUTHORITY_INVALID,
11222 ERR_CERT_DATE_INVALID,
11223 };
11224 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611225 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11226 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411227 }
11228}
11229
[email protected]bd0b6772011-01-11 19:59:3011230// Ensure that a client certificate is removed from the SSL client auth
11231// cache when:
11232// 1) No proxy is involved.
11233// 2) TLS False Start is disabled.
11234// 3) The initial TLS handshake requests a client certificate.
11235// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211236TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311237 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911238 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711239 request_info.url = GURL("https://www.example.com/");
11240 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911241 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711242
[email protected]bd0b6772011-01-11 19:59:3011243 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111244 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011245
11246 // [ssl_]data1 contains the data for the first SSL handshake. When a
11247 // CertificateRequest is received for the first time, the handshake will
11248 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911249 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011250 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711251 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911252 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711253 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011254
11255 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11256 // False Start is not being used, the result of the SSL handshake will be
11257 // returned as part of the SSLClientSocket::Connect() call. This test
11258 // matches the result of a server sending a handshake_failure alert,
11259 // rather than a Finished message, because it requires a client
11260 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911261 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011262 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711263 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911264 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711265 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011266
11267 // [ssl_]data3 contains the data for the third SSL handshake. When a
11268 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211269 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
11270 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011271 // of the HttpNetworkTransaction. Because this test failure is due to
11272 // requiring a client certificate, this fallback handshake should also
11273 // fail.
ttuttle859dc7a2015-04-23 19:42:2911274 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011275 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711276 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911277 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711278 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011279
[email protected]80c75f682012-05-26 16:22:1711280 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
11281 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211282 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
11283 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1711284 // of the HttpNetworkTransaction. Because this test failure is due to
11285 // requiring a client certificate, this fallback handshake should also
11286 // fail.
ttuttle859dc7a2015-04-23 19:42:2911287 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711288 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711289 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911290 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711291 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711292
[email protected]bb88e1d32013-05-03 23:11:0711293 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611294 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011296
[email protected]bd0b6772011-01-11 19:59:3011297 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111298 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911299 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11300 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011301
11302 // Complete the SSL handshake, which should abort due to requiring a
11303 // client certificate.
11304 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911305 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011306
11307 // Indicate that no certificate should be supplied. From the perspective
11308 // of SSLClientCertCache, NULL is just as meaningful as a real
11309 // certificate, so this is the same as supply a
11310 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111311 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911312 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011313
11314 // Ensure the certificate was added to the client auth cache before
11315 // allowing the connection to continue restarting.
11316 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111317 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11318 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011319 ASSERT_EQ(NULL, client_cert.get());
11320
11321 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711322 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11323 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011324 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911325 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011326
11327 // Ensure that the client certificate is removed from the cache on a
11328 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111329 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11330 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011331}
11332
11333// Ensure that a client certificate is removed from the SSL client auth
11334// cache when:
11335// 1) No proxy is involved.
11336// 2) TLS False Start is enabled.
11337// 3) The initial TLS handshake requests a client certificate.
11338// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211339TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311340 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911341 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711342 request_info.url = GURL("https://www.example.com/");
11343 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911344 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711345
[email protected]bd0b6772011-01-11 19:59:3011346 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111347 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011348
11349 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11350 // return successfully after reading up to the peer's Certificate message.
11351 // This is to allow the caller to call SSLClientSocket::Write(), which can
11352 // enqueue application data to be sent in the same packet as the
11353 // ChangeCipherSpec and Finished messages.
11354 // The actual handshake will be finished when SSLClientSocket::Read() is
11355 // called, which expects to process the peer's ChangeCipherSpec and
11356 // Finished messages. If there was an error negotiating with the peer,
11357 // such as due to the peer requiring a client certificate when none was
11358 // supplied, the alert sent by the peer won't be processed until Read() is
11359 // called.
11360
11361 // Like the non-False Start case, when a client certificate is requested by
11362 // the peer, the handshake is aborted during the Connect() call.
11363 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911364 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011365 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711366 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911367 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711368 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011369
11370 // When a client certificate is supplied, Connect() will not be aborted
11371 // when the peer requests the certificate. Instead, the handshake will
11372 // artificially succeed, allowing the caller to write the HTTP request to
11373 // the socket. The handshake messages are not processed until Read() is
11374 // called, which then detects that the handshake was aborted, due to the
11375 // peer sending a handshake_failure because it requires a client
11376 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911377 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011378 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711379 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911380 MockRead data2_reads[] = {
11381 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011382 };
ttuttle859dc7a2015-04-23 19:42:2911383 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711384 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011385
11386 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711387 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11388 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911389 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011390 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911392 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711393 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011394
[email protected]80c75f682012-05-26 16:22:1711395 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11396 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911397 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711398 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711399 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911400 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711401 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711402
[email protected]7799de12013-05-30 05:52:5111403 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911404 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111405 ssl_data5.cert_request_info = cert_request.get();
11406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911407 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111408 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11409
[email protected]bb88e1d32013-05-03 23:11:0711410 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611411 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011412 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011413
[email protected]bd0b6772011-01-11 19:59:3011414 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111415 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911416 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11417 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011418
11419 // Complete the SSL handshake, which should abort due to requiring a
11420 // client certificate.
11421 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911422 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011423
11424 // Indicate that no certificate should be supplied. From the perspective
11425 // of SSLClientCertCache, NULL is just as meaningful as a real
11426 // certificate, so this is the same as supply a
11427 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111428 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911429 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011430
11431 // Ensure the certificate was added to the client auth cache before
11432 // allowing the connection to continue restarting.
11433 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111434 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11435 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011436 ASSERT_EQ(NULL, client_cert.get());
11437
[email protected]bd0b6772011-01-11 19:59:3011438 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711439 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11440 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011441 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911442 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011443
11444 // Ensure that the client certificate is removed from the cache on a
11445 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111446 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11447 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011448}
11449
[email protected]8c405132011-01-11 22:03:1811450// Ensure that a client certificate is removed from the SSL client auth
11451// cache when:
11452// 1) An HTTPS proxy is involved.
11453// 3) The HTTPS proxy requests a client certificate.
11454// 4) The client supplies an invalid/unacceptable certificate for the
11455// proxy.
11456// The test is repeated twice, first for connecting to an HTTPS endpoint,
11457// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211458TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711459 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811460 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:5111461 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711462 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811463
11464 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111465 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811466
11467 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11468 // [ssl_]data[1-3]. Rather than represending the endpoint
11469 // (www.example.com:443), they represent failures with the HTTPS proxy
11470 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911471 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811472 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711473 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911474 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711475 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811476
ttuttle859dc7a2015-04-23 19:42:2911477 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811478 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711479 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911480 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711481 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811482
[email protected]80c75f682012-05-26 16:22:1711483 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11484#if 0
ttuttle859dc7a2015-04-23 19:42:2911485 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811486 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711487 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911488 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711489 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711490#endif
[email protected]8c405132011-01-11 22:03:1811491
ttuttle859dc7a2015-04-23 19:42:2911492 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811493 requests[0].url = GURL("https://www.example.com/");
11494 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911495 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811496
11497 requests[1].url = GURL("http://www.example.com/");
11498 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911499 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811500
11501 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711502 session_deps_.socket_factory->ResetNextMockIndexes();
11503 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811504 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011505 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811506
11507 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111508 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911509 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11510 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811511
11512 // Complete the SSL handshake, which should abort due to requiring a
11513 // client certificate.
11514 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911515 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811516
11517 // Indicate that no certificate should be supplied. From the perspective
11518 // of SSLClientCertCache, NULL is just as meaningful as a real
11519 // certificate, so this is the same as supply a
11520 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111521 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911522 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811523
11524 // Ensure the certificate was added to the client auth cache before
11525 // allowing the connection to continue restarting.
11526 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111527 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11528 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811529 ASSERT_EQ(NULL, client_cert.get());
11530 // Ensure the certificate was NOT cached for the endpoint. This only
11531 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111532 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11533 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811534
11535 // Restart the handshake. This will consume ssl_data2, which fails, and
11536 // then consume ssl_data3, which should also fail. The result code is
11537 // checked against what ssl_data3 should return.
11538 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911539 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811540
11541 // Now that the new handshake has failed, ensure that the client
11542 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111543 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11544 HostPortPair("proxy", 70), &client_cert));
11545 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11546 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811547 }
11548}
11549
mmenke5c642132015-06-02 16:05:1311550TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2311551 session_deps_.use_alternate_protocols = true;
11552 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611553
11554 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711555 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11556 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611557 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11558 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611559
[email protected]8ddf8322012-02-23 18:08:0611560 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211561 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711562 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611563
[email protected]cdf8f7e72013-05-23 10:56:4611564 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311565 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611566 scoped_ptr<SpdyFrame> host2_req(
11567 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611568 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311569 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611570 };
[email protected]23e482282013-06-14 16:08:0211571 scoped_ptr<SpdyFrame> host1_resp(
11572 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11573 scoped_ptr<SpdyFrame> host1_resp_body(
11574 spdy_util_.ConstructSpdyBodyFrame(1, true));
11575 scoped_ptr<SpdyFrame> host2_resp(
11576 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11577 scoped_ptr<SpdyFrame> host2_resp_body(
11578 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611579 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311580 CreateMockRead(*host1_resp, 1),
11581 CreateMockRead(*host1_resp_body, 2),
11582 CreateMockRead(*host2_resp, 4),
11583 CreateMockRead(*host2_resp_body, 5),
11584 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611585 };
11586
[email protected]d2b5f092012-06-08 23:55:0211587 IPAddressNumber ip;
11588 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11589 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11590 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311591 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11592 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711593 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611594
[email protected]aa22b242011-11-16 18:58:2911595 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611596 HttpRequestInfo request1;
11597 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311598 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611599 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011600 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611601
[email protected]49639fa2011-12-20 23:22:4111602 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611603 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111604 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611605
11606 const HttpResponseInfo* response = trans1.GetResponseInfo();
11607 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011608 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611609 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11610
11611 std::string response_data;
11612 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11613 EXPECT_EQ("hello!", response_data);
11614
11615 // Preload www.gmail.com into HostCache.
11616 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011617 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611618 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011619 rv = session_deps_.host_resolver->Resolve(resolve_info,
11620 DEFAULT_PRIORITY,
11621 &ignored,
11622 callback.callback(),
11623 NULL,
11624 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711625 EXPECT_EQ(ERR_IO_PENDING, rv);
11626 rv = callback.WaitForResult();
11627 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611628
11629 HttpRequestInfo request2;
11630 request2.method = "GET";
11631 request2.url = GURL("https://www.gmail.com/");
11632 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011633 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611634
[email protected]49639fa2011-12-20 23:22:4111635 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611636 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111637 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611638
11639 response = trans2.GetResponseInfo();
11640 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011641 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611642 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11643 EXPECT_TRUE(response->was_fetched_via_spdy);
11644 EXPECT_TRUE(response->was_npn_negotiated);
11645 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11646 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611647}
11648
[email protected]23e482282013-06-14 16:08:0211649TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311650 session_deps_.use_alternate_protocols = true;
11651 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211652
11653 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711654 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11655 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211656 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11657 pool_peer.DisableDomainAuthenticationVerification();
11658
11659 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211660 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711661 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211662
[email protected]cdf8f7e72013-05-23 10:56:4611663 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311664 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611665 scoped_ptr<SpdyFrame> host2_req(
11666 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211667 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311668 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0211669 };
[email protected]23e482282013-06-14 16:08:0211670 scoped_ptr<SpdyFrame> host1_resp(
11671 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11672 scoped_ptr<SpdyFrame> host1_resp_body(
11673 spdy_util_.ConstructSpdyBodyFrame(1, true));
11674 scoped_ptr<SpdyFrame> host2_resp(
11675 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11676 scoped_ptr<SpdyFrame> host2_resp_body(
11677 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211678 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311679 CreateMockRead(*host1_resp, 1),
11680 CreateMockRead(*host1_resp_body, 2),
11681 CreateMockRead(*host2_resp, 4),
11682 CreateMockRead(*host2_resp_body, 5),
11683 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0211684 };
11685
11686 IPAddressNumber ip;
11687 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11688 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11689 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311690 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11691 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711692 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211693
11694 TestCompletionCallback callback;
11695 HttpRequestInfo request1;
11696 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311697 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0211698 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011699 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211700
11701 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11702 EXPECT_EQ(ERR_IO_PENDING, rv);
11703 EXPECT_EQ(OK, callback.WaitForResult());
11704
11705 const HttpResponseInfo* response = trans1.GetResponseInfo();
11706 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011707 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211708 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11709
11710 std::string response_data;
11711 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11712 EXPECT_EQ("hello!", response_data);
11713
11714 HttpRequestInfo request2;
11715 request2.method = "GET";
11716 request2.url = GURL("https://www.gmail.com/");
11717 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011718 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211719
11720 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11721 EXPECT_EQ(ERR_IO_PENDING, rv);
11722 EXPECT_EQ(OK, callback.WaitForResult());
11723
11724 response = trans2.GetResponseInfo();
11725 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011726 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211727 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11728 EXPECT_TRUE(response->was_fetched_via_spdy);
11729 EXPECT_TRUE(response->was_npn_negotiated);
11730 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11731 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211732}
11733
ttuttle859dc7a2015-04-23 19:42:2911734class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4611735 public:
11736 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11737 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011738 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611739
11740 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11741
11742 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011743 int Resolve(const RequestInfo& info,
11744 RequestPriority priority,
11745 AddressList* addresses,
11746 const CompletionCallback& callback,
11747 RequestHandle* out_req,
11748 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011749 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011750 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011751 }
11752
dchengb03027d2014-10-21 12:00:2011753 int ResolveFromCache(const RequestInfo& info,
11754 AddressList* addresses,
11755 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011756 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11757 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911758 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611759 return rv;
11760 }
11761
dchengb03027d2014-10-21 12:00:2011762 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611763 host_resolver_.CancelRequest(req);
11764 }
11765
[email protected]46da33be2011-07-19 21:58:0411766 MockCachingHostResolver* GetMockHostResolver() {
11767 return &host_resolver_;
11768 }
11769
[email protected]e3ceb682011-06-28 23:55:4611770 private:
11771 MockCachingHostResolver host_resolver_;
11772 const HostPortPair host_port_;
11773};
11774
mmenke5c642132015-06-02 16:05:1311775TEST_P(HttpNetworkTransactionTest,
11776 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]d7599122014-05-24 03:37:2311777 session_deps_.use_alternate_protocols = true;
11778 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611779
11780 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611781 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411782 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711783 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611784 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711785 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611786 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11787 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611788
[email protected]8ddf8322012-02-23 18:08:0611789 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211790 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711791 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611792
[email protected]cdf8f7e72013-05-23 10:56:4611793 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311794 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611795 scoped_ptr<SpdyFrame> host2_req(
11796 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611797 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311798 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611799 };
[email protected]23e482282013-06-14 16:08:0211800 scoped_ptr<SpdyFrame> host1_resp(
11801 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11802 scoped_ptr<SpdyFrame> host1_resp_body(
11803 spdy_util_.ConstructSpdyBodyFrame(1, true));
11804 scoped_ptr<SpdyFrame> host2_resp(
11805 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11806 scoped_ptr<SpdyFrame> host2_resp_body(
11807 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611808 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311809 CreateMockRead(*host1_resp, 1),
11810 CreateMockRead(*host1_resp_body, 2),
11811 CreateMockRead(*host2_resp, 4),
11812 CreateMockRead(*host2_resp_body, 5),
11813 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611814 };
11815
[email protected]d2b5f092012-06-08 23:55:0211816 IPAddressNumber ip;
11817 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11818 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11819 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311820 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11821 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711822 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611823
[email protected]aa22b242011-11-16 18:58:2911824 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611825 HttpRequestInfo request1;
11826 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311827 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611828 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011829 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611830
[email protected]49639fa2011-12-20 23:22:4111831 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611832 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111833 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611834
11835 const HttpResponseInfo* response = trans1.GetResponseInfo();
11836 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011837 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611838 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11839
11840 std::string response_data;
11841 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11842 EXPECT_EQ("hello!", response_data);
11843
11844 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011845 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611846 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011847 rv = host_resolver.Resolve(resolve_info,
11848 DEFAULT_PRIORITY,
11849 &ignored,
11850 callback.callback(),
11851 NULL,
11852 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711853 EXPECT_EQ(ERR_IO_PENDING, rv);
11854 rv = callback.WaitForResult();
11855 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611856
11857 HttpRequestInfo request2;
11858 request2.method = "GET";
11859 request2.url = GURL("https://www.gmail.com/");
11860 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011861 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611862
[email protected]49639fa2011-12-20 23:22:4111863 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611864 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111865 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611866
11867 response = trans2.GetResponseInfo();
11868 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011869 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611870 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11871 EXPECT_TRUE(response->was_fetched_via_spdy);
11872 EXPECT_TRUE(response->was_npn_negotiated);
11873 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11874 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611875}
11876
[email protected]23e482282013-06-14 16:08:0211877TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2311878 const std::string https_url = "https://www.example.org:8080/";
11879 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0411880
11881 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611882 scoped_ptr<SpdyFrame> req1(
11883 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411884
11885 MockWrite writes1[] = {
11886 CreateMockWrite(*req1, 0),
11887 };
11888
[email protected]23e482282013-06-14 16:08:0211889 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11890 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411891 MockRead reads1[] = {
11892 CreateMockRead(*resp1, 1),
11893 CreateMockRead(*body1, 2),
11894 MockRead(ASYNC, ERR_IO_PENDING, 3)
11895 };
11896
rch8e6c6c42015-05-01 14:05:1311897 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
11898 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411899 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711900 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411901
11902 // HTTP GET for the HTTP URL
11903 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1311904 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3411905 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2311906 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3411907 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0411908 };
11909
11910 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1311911 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11912 MockRead(ASYNC, 2, "hello"),
11913 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0411914 };
11915
rch8e6c6c42015-05-01 14:05:1311916 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
11917 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411918
[email protected]8450d722012-07-02 19:14:0411919 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211920 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711921 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11922 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11923 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411924
[email protected]bb88e1d32013-05-03 23:11:0711925 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411926
11927 // Start the first transaction to set up the SpdySession
11928 HttpRequestInfo request1;
11929 request1.method = "GET";
11930 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411931 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011932 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411933 TestCompletionCallback callback1;
11934 EXPECT_EQ(ERR_IO_PENDING,
11935 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411936 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411937
11938 EXPECT_EQ(OK, callback1.WaitForResult());
11939 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11940
11941 // Now, start the HTTP request
11942 HttpRequestInfo request2;
11943 request2.method = "GET";
11944 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411945 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011946 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411947 TestCompletionCallback callback2;
11948 EXPECT_EQ(ERR_IO_PENDING,
11949 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411950 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411951
11952 EXPECT_EQ(OK, callback2.WaitForResult());
11953 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11954}
11955
bnc1b0e36852015-04-28 15:32:5911956class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
11957 public:
11958 void Run(bool pooling, bool valid) {
11959 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
11960 443);
11961 HostPortPair alternative("www.example.org", 443);
11962
11963 base::FilePath certs_dir = GetTestCertsDirectory();
11964 scoped_refptr<X509Certificate> cert(
11965 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
11966 ASSERT_TRUE(cert.get());
11967 bool common_name_fallback_used;
11968 EXPECT_EQ(valid,
11969 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
11970 EXPECT_TRUE(
11971 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
11972 SSLSocketDataProvider ssl(ASYNC, OK);
11973 ssl.SetNextProto(GetParam());
11974 ssl.cert = cert;
11975 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11976
11977 // If pooling, then start a request to alternative first to create a
11978 // SpdySession.
11979 std::string url0 = "https://www.example.org:443";
11980 // Second request to origin, which has an alternative service, and could
11981 // open a connection to the alternative host or pool to the existing one.
11982 std::string url1("https://");
11983 url1.append(origin.host());
11984 url1.append(":443");
11985
11986 scoped_ptr<SpdyFrame> req0;
11987 scoped_ptr<SpdyFrame> req1;
11988 scoped_ptr<SpdyFrame> resp0;
11989 scoped_ptr<SpdyFrame> body0;
11990 scoped_ptr<SpdyFrame> resp1;
11991 scoped_ptr<SpdyFrame> body1;
11992 std::vector<MockWrite> writes;
11993 std::vector<MockRead> reads;
11994
11995 if (pooling) {
11996 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
11997 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
11998
11999 writes.push_back(CreateMockWrite(*req0, 0));
12000 writes.push_back(CreateMockWrite(*req1, 3));
12001
12002 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12003 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12004 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12005 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
12006
12007 reads.push_back(CreateMockRead(*resp0, 1));
12008 reads.push_back(CreateMockRead(*body0, 2));
12009 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
12010 reads.push_back(CreateMockRead(*resp1, 5));
12011 reads.push_back(CreateMockRead(*body1, 6));
12012 reads.push_back(MockRead(ASYNC, OK, 7));
12013 } else {
12014 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
12015
12016 writes.push_back(CreateMockWrite(*req1, 0));
12017
12018 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12019 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12020
12021 reads.push_back(CreateMockRead(*resp1, 1));
12022 reads.push_back(CreateMockRead(*body1, 2));
12023 reads.push_back(MockRead(ASYNC, OK, 3));
12024 }
12025
rch32320842015-05-16 15:57:0912026 SequencedSocketData data(vector_as_array(&reads), reads.size(),
12027 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5912028 session_deps_.socket_factory->AddSocketDataProvider(&data);
12029
12030 // Connection to the origin fails.
12031 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12032 StaticSocketDataProvider data_refused;
12033 data_refused.set_connect_data(mock_connect);
12034 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12035
12036 session_deps_.use_alternate_protocols = true;
12037 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12038 base::WeakPtr<HttpServerProperties> http_server_properties =
12039 session->http_server_properties();
12040 AlternativeService alternative_service(
12041 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212042 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc1b0e36852015-04-28 15:32:5912043 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212044 1.0, expiration);
bnc1b0e36852015-04-28 15:32:5912045
12046 // First request to alternative.
12047 if (pooling) {
12048 scoped_ptr<HttpTransaction> trans0(
12049 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12050 HttpRequestInfo request0;
12051 request0.method = "GET";
12052 request0.url = GURL(url0);
12053 request0.load_flags = 0;
12054 TestCompletionCallback callback0;
12055
12056 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
12057 EXPECT_EQ(ERR_IO_PENDING, rv);
12058 rv = callback0.WaitForResult();
12059 EXPECT_EQ(OK, rv);
12060 }
12061
12062 // Second request to origin.
12063 scoped_ptr<HttpTransaction> trans1(
12064 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12065 HttpRequestInfo request1;
12066 request1.method = "GET";
12067 request1.url = GURL(url1);
12068 request1.load_flags = 0;
12069 TestCompletionCallback callback1;
12070
12071 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12072 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0912073 base::MessageLoop::current()->RunUntilIdle();
12074 if (data.IsReadPaused()) {
12075 data.CompleteRead();
12076 }
bnc1b0e36852015-04-28 15:32:5912077 rv = callback1.WaitForResult();
12078 if (valid) {
12079 EXPECT_EQ(OK, rv);
12080 } else {
12081 if (pooling) {
12082 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12083 } else {
12084 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
12085 }
12086 }
12087 }
12088};
12089
12090INSTANTIATE_TEST_CASE_P(NextProto,
12091 AltSvcCertificateVerificationTest,
12092 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:4312093 kProtoHTTP2_14,
12094 kProtoHTTP2));
bnc1b0e36852015-04-28 15:32:5912095
12096// The alternative service host must exhibit a certificate that is valid for the
12097// origin host. Test that this is enforced when pooling to an existing
12098// connection.
12099TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
12100 Run(true, true);
12101}
12102
12103TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
12104 Run(true, false);
12105}
12106
12107// The alternative service host must exhibit a certificate that is valid for the
12108// origin host. Test that this is enforced when opening a new connection.
12109TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
12110 Run(false, true);
12111}
12112
12113TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
12114 Run(false, false);
12115}
12116
bnc5452e2a2015-05-08 16:27:4212117// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
12118// with the alternative server. That connection should not be used.
12119TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
12120 HostPortPair origin("origin.example.org", 443);
12121 HostPortPair alternative("alternative.example.org", 443);
12122
12123 // Negotiate HTTP/1.1 with alternative.example.org.
12124 SSLSocketDataProvider ssl(ASYNC, OK);
12125 ssl.SetNextProto(kProtoHTTP11);
12126 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12127
12128 // No data should be read from the alternative, because HTTP/1.1 is
12129 // negotiated.
12130 StaticSocketDataProvider data;
12131 session_deps_.socket_factory->AddSocketDataProvider(&data);
12132
12133 // This test documents that an alternate Job should not be used if HTTP/1.1 is
12134 // negotiated. In order to test this, a failed connection to the origin is
12135 // mocked. This way the request relies on the alternate Job.
12136 StaticSocketDataProvider data_refused;
12137 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12138 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12139
12140 // Set up alternative service for origin.
12141 session_deps_.use_alternate_protocols = true;
12142 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12143 base::WeakPtr<HttpServerProperties> http_server_properties =
12144 session->http_server_properties();
12145 AlternativeService alternative_service(
12146 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212147 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212148 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212149 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212150
12151 scoped_ptr<HttpTransaction> trans(
12152 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12153 HttpRequestInfo request;
12154 request.method = "GET";
12155 request.url = GURL("https://origin.example.org:443");
12156 request.load_flags = 0;
12157 TestCompletionCallback callback;
12158
12159 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
12160 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
12161 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12162 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
12163}
12164
bnc40448a532015-05-11 19:13:1412165// A request to a server with an alternative service fires two Jobs: one to the
12166// origin, and an alternate one to the alternative server. If the former
12167// succeeds, the request should succeed, even if the latter fails because
12168// HTTP/1.1 is negotiated which is insufficient for alternative service.
12169TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
12170 HostPortPair origin("origin.example.org", 443);
12171 HostPortPair alternative("alternative.example.org", 443);
12172
12173 // Negotiate HTTP/1.1 with alternative.
12174 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
12175 alternative_ssl.SetNextProto(kProtoHTTP11);
12176 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
12177
12178 // No data should be read from the alternative, because HTTP/1.1 is
12179 // negotiated.
12180 StaticSocketDataProvider data;
12181 session_deps_.socket_factory->AddSocketDataProvider(&data);
12182
12183 // Negotiate HTTP/1.1 with origin.
12184 SSLSocketDataProvider origin_ssl(ASYNC, OK);
12185 origin_ssl.SetNextProto(kProtoHTTP11);
12186 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
12187
12188 MockWrite http_writes[] = {
12189 MockWrite(
12190 "GET / HTTP/1.1\r\n"
12191 "Host: origin.example.org\r\n"
12192 "Connection: keep-alive\r\n\r\n"),
12193 MockWrite(
12194 "GET /second HTTP/1.1\r\n"
12195 "Host: origin.example.org\r\n"
12196 "Connection: keep-alive\r\n\r\n"),
12197 };
12198
12199 MockRead http_reads[] = {
12200 MockRead("HTTP/1.1 200 OK\r\n"),
12201 MockRead("Content-Type: text/html\r\n"),
12202 MockRead("Content-Length: 6\r\n\r\n"),
12203 MockRead("foobar"),
12204 MockRead("HTTP/1.1 200 OK\r\n"),
12205 MockRead("Content-Type: text/html\r\n"),
12206 MockRead("Content-Length: 7\r\n\r\n"),
12207 MockRead("another"),
12208 };
12209 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12210 http_writes, arraysize(http_writes));
12211 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12212
12213 // Set up alternative service for origin.
12214 session_deps_.use_alternate_protocols = true;
12215 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12216 base::WeakPtr<HttpServerProperties> http_server_properties =
12217 session->http_server_properties();
12218 AlternativeService alternative_service(
12219 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212220 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc40448a532015-05-11 19:13:1412221 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212222 1.0, expiration);
bnc40448a532015-05-11 19:13:1412223
12224 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
12225 HttpRequestInfo request1;
12226 request1.method = "GET";
12227 request1.url = GURL("https://origin.example.org:443");
12228 request1.load_flags = 0;
12229 TestCompletionCallback callback1;
12230
12231 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
12232 rv = callback1.GetResult(rv);
12233 EXPECT_EQ(OK, rv);
12234
12235 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
12236 ASSERT_TRUE(response1 != nullptr);
12237 ASSERT_TRUE(response1->headers.get() != nullptr);
12238 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12239
12240 std::string response_data1;
12241 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
12242 EXPECT_EQ("foobar", response_data1);
12243
12244 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
12245 // for alternative service.
12246 EXPECT_TRUE(
12247 http_server_properties->IsAlternativeServiceBroken(alternative_service));
12248
12249 // Since |alternative_service| is broken, a second transaction to origin
12250 // should not start an alternate Job. It should pool to existing connection
12251 // to origin.
12252 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
12253 HttpRequestInfo request2;
12254 request2.method = "GET";
12255 request2.url = GURL("https://origin.example.org:443/second");
12256 request2.load_flags = 0;
12257 TestCompletionCallback callback2;
12258
12259 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
12260 rv = callback2.GetResult(rv);
12261 EXPECT_EQ(OK, rv);
12262
12263 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
12264 ASSERT_TRUE(response2 != nullptr);
12265 ASSERT_TRUE(response2->headers.get() != nullptr);
12266 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
12267
12268 std::string response_data2;
12269 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
12270 EXPECT_EQ("another", response_data2);
12271}
12272
bnc5452e2a2015-05-08 16:27:4212273// Alternative service requires HTTP/2 (or SPDY), but there is already a
12274// HTTP/1.1 socket open to the alternative server. That socket should not be
12275// used.
12276TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12277 HostPortPair origin("origin.example.org", 443);
12278 HostPortPair alternative("alternative.example.org", 443);
12279 std::string origin_url = "https://origin.example.org:443";
12280 std::string alternative_url = "https://alternative.example.org:443";
12281
12282 // Negotiate HTTP/1.1 with alternative.example.org.
12283 SSLSocketDataProvider ssl(ASYNC, OK);
12284 ssl.SetNextProto(kProtoHTTP11);
12285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12286
12287 // HTTP/1.1 data for |request1| and |request2|.
12288 MockWrite http_writes[] = {
12289 MockWrite(
12290 "GET / HTTP/1.1\r\n"
12291 "Host: alternative.example.org\r\n"
12292 "Connection: keep-alive\r\n\r\n"),
12293 MockWrite(
12294 "GET / HTTP/1.1\r\n"
12295 "Host: alternative.example.org\r\n"
12296 "Connection: keep-alive\r\n\r\n"),
12297 };
12298
12299 MockRead http_reads[] = {
12300 MockRead(
12301 "HTTP/1.1 200 OK\r\n"
12302 "Content-Type: text/html; charset=iso-8859-1\r\n"
12303 "Content-Length: 40\r\n\r\n"
12304 "first HTTP/1.1 response from alternative"),
12305 MockRead(
12306 "HTTP/1.1 200 OK\r\n"
12307 "Content-Type: text/html; charset=iso-8859-1\r\n"
12308 "Content-Length: 41\r\n\r\n"
12309 "second HTTP/1.1 response from alternative"),
12310 };
12311 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12312 http_writes, arraysize(http_writes));
12313 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12314
12315 // This test documents that an alternate Job should not pool to an already
12316 // existing HTTP/1.1 connection. In order to test this, a failed connection
12317 // to the origin is mocked. This way |request2| relies on the alternate Job.
12318 StaticSocketDataProvider data_refused;
12319 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12320 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12321
12322 // Set up alternative service for origin.
12323 session_deps_.use_alternate_protocols = true;
12324 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12325 base::WeakPtr<HttpServerProperties> http_server_properties =
12326 session->http_server_properties();
12327 AlternativeService alternative_service(
12328 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212329 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212330 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212331 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212332
12333 // First transaction to alternative to open an HTTP/1.1 socket.
12334 scoped_ptr<HttpTransaction> trans1(
12335 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12336 HttpRequestInfo request1;
12337 request1.method = "GET";
12338 request1.url = GURL(alternative_url);
12339 request1.load_flags = 0;
12340 TestCompletionCallback callback1;
12341
12342 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12343 EXPECT_EQ(OK, callback1.GetResult(rv));
12344 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12345 ASSERT_TRUE(response1);
12346 ASSERT_TRUE(response1->headers.get());
12347 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12348 EXPECT_TRUE(response1->was_npn_negotiated);
12349 EXPECT_FALSE(response1->was_fetched_via_spdy);
12350 std::string response_data1;
12351 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12352 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12353
12354 // Request for origin.example.org, which has an alternative service. This
12355 // will start two Jobs: the alternative looks for connections to pool to,
12356 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12357 // open other connections to alternative server. The Job to origin fails, so
12358 // this request fails.
12359 scoped_ptr<HttpTransaction> trans2(
12360 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12361 HttpRequestInfo request2;
12362 request2.method = "GET";
12363 request2.url = GURL(origin_url);
12364 request2.load_flags = 0;
12365 TestCompletionCallback callback2;
12366
12367 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12368 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12369
12370 // Another transaction to alternative. This is to test that the HTTP/1.1
12371 // socket is still open and in the pool.
12372 scoped_ptr<HttpTransaction> trans3(
12373 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12374 HttpRequestInfo request3;
12375 request3.method = "GET";
12376 request3.url = GURL(alternative_url);
12377 request3.load_flags = 0;
12378 TestCompletionCallback callback3;
12379
12380 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12381 EXPECT_EQ(OK, callback3.GetResult(rv));
12382 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12383 ASSERT_TRUE(response3);
12384 ASSERT_TRUE(response3->headers.get());
12385 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12386 EXPECT_TRUE(response3->was_npn_negotiated);
12387 EXPECT_FALSE(response3->was_fetched_via_spdy);
12388 std::string response_data3;
12389 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12390 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12391}
12392
[email protected]23e482282013-06-14 16:08:0212393TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2312394 const std::string https_url = "https://www.example.org:8080/";
12395 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412396
12397 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2312398 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3412399 scoped_ptr<SpdyFrame> connect(
12400 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4612401 scoped_ptr<SpdyFrame> req1(
12402 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0212403 scoped_ptr<SpdyFrame> wrapped_req1(
12404 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3912405
12406 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2912407 SpdyHeaderBlock req2_block;
12408 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3812409 req2_block[spdy_util_.GetPathKey()] = "/";
bncce36dca22015-04-21 22:11:2312410 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2912411 req2_block[spdy_util_.GetSchemeKey()] = "http";
12412 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3912413 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2912414 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0412415
12416 MockWrite writes1[] = {
12417 CreateMockWrite(*connect, 0),
12418 CreateMockWrite(*wrapped_req1, 2),
12419 CreateMockWrite(*req2, 5),
12420 };
12421
[email protected]23e482282013-06-14 16:08:0212422 scoped_ptr<SpdyFrame> conn_resp(
12423 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12424 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12425 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12426 scoped_ptr<SpdyFrame> wrapped_resp1(
12427 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12428 scoped_ptr<SpdyFrame> wrapped_body1(
12429 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12430 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12431 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412432 MockRead reads1[] = {
12433 CreateMockRead(*conn_resp, 1),
12434 CreateMockRead(*wrapped_resp1, 3),
12435 CreateMockRead(*wrapped_body1, 4),
12436 CreateMockRead(*resp2, 6),
12437 CreateMockRead(*body2, 7),
12438 MockRead(ASYNC, ERR_IO_PENDING, 8)
12439 };
12440
[email protected]dd54bd82012-07-19 23:44:5712441 DeterministicSocketData data1(reads1, arraysize(reads1),
12442 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412443 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712444 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412445
[email protected]bb88e1d32013-05-03 23:11:0712446 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2212447 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:5112448 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712449 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412450 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212451 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712452 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412453 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212454 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712455 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12456 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412457
12458 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712459 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412460
12461 // Start the first transaction to set up the SpdySession
12462 HttpRequestInfo request1;
12463 request1.method = "GET";
12464 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412465 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012466 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412467 TestCompletionCallback callback1;
12468 EXPECT_EQ(ERR_IO_PENDING,
12469 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412470 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712471 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412472
12473 EXPECT_EQ(OK, callback1.WaitForResult());
12474 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12475
[email protected]f6c63db52013-02-02 00:35:2212476 LoadTimingInfo load_timing_info1;
12477 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12478 TestLoadTimingNotReusedWithPac(load_timing_info1,
12479 CONNECT_TIMING_HAS_SSL_TIMES);
12480
[email protected]8450d722012-07-02 19:14:0412481 // Now, start the HTTP request
12482 HttpRequestInfo request2;
12483 request2.method = "GET";
12484 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412485 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012486 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412487 TestCompletionCallback callback2;
12488 EXPECT_EQ(ERR_IO_PENDING,
12489 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412490 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712491 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412492
12493 EXPECT_EQ(OK, callback2.WaitForResult());
12494 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212495
12496 LoadTimingInfo load_timing_info2;
12497 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12498 // The established SPDY sessions is considered reused by the HTTP request.
12499 TestLoadTimingReusedWithPac(load_timing_info2);
12500 // HTTP requests over a SPDY session should have a different connection
12501 // socket_log_id than requests over a tunnel.
12502 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412503}
12504
[email protected]2d88e7d2012-07-19 17:55:1712505// Test that in the case where we have a SPDY session to a SPDY proxy
12506// that we do not pool other origins that resolve to the same IP when
12507// the certificate does not match the new origin.
12508// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212509TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312510 const std::string url1 = "http://www.example.org/";
12511 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712512 const std::string ip_addr = "1.2.3.4";
12513
12514 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212515 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312516 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912517 scoped_ptr<SpdyFrame> req1(
12518 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712519
12520 MockWrite writes1[] = {
12521 CreateMockWrite(*req1, 0),
12522 };
12523
[email protected]23e482282013-06-14 16:08:0212524 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12525 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712526 MockRead reads1[] = {
bncb9e20fc62015-08-17 17:19:3712527 CreateMockRead(*resp1, 1),
12528 CreateMockRead(*body1, 2),
12529 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712530 };
12531
12532 scoped_ptr<DeterministicSocketData> data1(
12533 new DeterministicSocketData(reads1, arraysize(reads1),
12534 writes1, arraysize(writes1)));
12535 IPAddressNumber ip;
12536 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12537 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12538 MockConnect connect_data1(ASYNC, OK, peer_addr);
12539 data1->set_connect_data(connect_data1);
12540
12541 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612542 scoped_ptr<SpdyFrame> req2(
12543 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712544
12545 MockWrite writes2[] = {
12546 CreateMockWrite(*req2, 0),
12547 };
12548
[email protected]23e482282013-06-14 16:08:0212549 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12550 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712551 MockRead reads2[] = {
bncb9e20fc62015-08-17 17:19:3712552 CreateMockRead(*resp2, 1),
12553 CreateMockRead(*body2, 2),
12554 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712555 };
12556
12557 scoped_ptr<DeterministicSocketData> data2(
12558 new DeterministicSocketData(reads2, arraysize(reads2),
12559 writes2, arraysize(writes2)));
12560 MockConnect connect_data2(ASYNC, OK);
12561 data2->set_connect_data(connect_data2);
12562
12563 // Set up a proxy config that sends HTTP requests to a proxy, and
12564 // all others direct.
12565 ProxyConfig proxy_config;
12566 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712567 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:1312568 new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
[email protected]2d88e7d2012-07-19 17:55:1712569
bncce36dca22015-04-21 22:11:2312570 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12571 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712572 // Load a valid cert. Note, that this does not need to
12573 // be valid for proxy because the MockSSLClientSocket does
12574 // not actually verify it. But SpdySession will use this
12575 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312576 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12577 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712578 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12579 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12580 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712581
12582 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212583 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712584 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12585 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12586 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712587
[email protected]bb88e1d32013-05-03 23:11:0712588 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312589 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712590 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712591
12592 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712593 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712594
12595 // Start the first transaction to set up the SpdySession
12596 HttpRequestInfo request1;
12597 request1.method = "GET";
12598 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712599 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012600 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712601 TestCompletionCallback callback1;
12602 ASSERT_EQ(ERR_IO_PENDING,
12603 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12604 data1->RunFor(3);
12605
12606 ASSERT_TRUE(callback1.have_result());
12607 EXPECT_EQ(OK, callback1.WaitForResult());
12608 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12609
12610 // Now, start the HTTP request
12611 HttpRequestInfo request2;
12612 request2.method = "GET";
12613 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712614 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012615 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712616 TestCompletionCallback callback2;
12617 EXPECT_EQ(ERR_IO_PENDING,
12618 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412619 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712620 data2->RunFor(3);
12621
12622 ASSERT_TRUE(callback2.have_result());
12623 EXPECT_EQ(OK, callback2.WaitForResult());
12624 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12625}
12626
[email protected]85f97342013-04-17 06:12:2412627// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12628// error) in SPDY session, removes the socket from pool and closes the SPDY
12629// session. Verify that new url's from the same HttpNetworkSession (and a new
12630// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212631TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312632 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412633
12634 MockRead reads1[] = {
12635 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12636 };
12637
mmenke11eb5152015-06-09 14:50:5012638 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2412639
[email protected]cdf8f7e72013-05-23 10:56:4612640 scoped_ptr<SpdyFrame> req2(
12641 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412642 MockWrite writes2[] = {
12643 CreateMockWrite(*req2, 0),
12644 };
12645
[email protected]23e482282013-06-14 16:08:0212646 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12647 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412648 MockRead reads2[] = {
12649 CreateMockRead(*resp2, 1),
12650 CreateMockRead(*body2, 2),
12651 MockRead(ASYNC, OK, 3) // EOF
12652 };
12653
mmenke11eb5152015-06-09 14:50:5012654 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12655 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2412656
[email protected]85f97342013-04-17 06:12:2412657 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212658 ssl1.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012659 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12660 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2412661
12662 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212663 ssl2.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012664 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12665 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2412666
12667 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5012668 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412669
12670 // Start the first transaction to set up the SpdySession and verify that
12671 // connection was closed.
12672 HttpRequestInfo request1;
12673 request1.method = "GET";
12674 request1.url = GURL(https_url);
12675 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012676 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412677 TestCompletionCallback callback1;
12678 EXPECT_EQ(ERR_IO_PENDING,
12679 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412680 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12681
12682 // Now, start the second request and make sure it succeeds.
12683 HttpRequestInfo request2;
12684 request2.method = "GET";
12685 request2.url = GURL(https_url);
12686 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012687 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412688 TestCompletionCallback callback2;
12689 EXPECT_EQ(ERR_IO_PENDING,
12690 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412691
mmenke11eb5152015-06-09 14:50:5012692 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2412693 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12694}
12695
[email protected]23e482282013-06-14 16:08:0212696TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312697 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312698 ClientSocketPoolManager::set_max_sockets_per_group(
12699 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12700 ClientSocketPoolManager::set_max_sockets_per_pool(
12701 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12702
12703 // Use two different hosts with different IPs so they don't get pooled.
12704 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12705 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
12706 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12707
12708 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212709 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312710 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212711 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312712 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12713 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12714
[email protected]cdf8f7e72013-05-23 10:56:4612715 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312716 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12717 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1312718 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0312719 };
[email protected]23e482282013-06-14 16:08:0212720 scoped_ptr<SpdyFrame> host1_resp(
12721 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12722 scoped_ptr<SpdyFrame> host1_resp_body(
12723 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312724 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1312725 CreateMockRead(*host1_resp, 1),
12726 CreateMockRead(*host1_resp_body, 2),
12727 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312728 };
12729
rch8e6c6c42015-05-01 14:05:1312730 scoped_ptr<SequencedSocketData> spdy1_data(
12731 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
12732 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0312733 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12734
[email protected]cdf8f7e72013-05-23 10:56:4612735 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312736 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12737 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1312738 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0312739 };
[email protected]23e482282013-06-14 16:08:0212740 scoped_ptr<SpdyFrame> host2_resp(
12741 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12742 scoped_ptr<SpdyFrame> host2_resp_body(
12743 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312744 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1312745 CreateMockRead(*host2_resp, 1),
12746 CreateMockRead(*host2_resp_body, 2),
12747 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312748 };
12749
rch8e6c6c42015-05-01 14:05:1312750 scoped_ptr<SequencedSocketData> spdy2_data(
12751 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
12752 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0312753 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12754
12755 MockWrite http_write[] = {
12756 MockWrite("GET / HTTP/1.1\r\n"
12757 "Host: www.a.com\r\n"
12758 "Connection: keep-alive\r\n\r\n"),
12759 };
12760
12761 MockRead http_read[] = {
12762 MockRead("HTTP/1.1 200 OK\r\n"),
12763 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12764 MockRead("Content-Length: 6\r\n\r\n"),
12765 MockRead("hello!"),
12766 };
12767 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12768 http_write, arraysize(http_write));
12769 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12770
12771 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012772 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312773 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312774 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612775 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312776
12777 TestCompletionCallback callback;
12778 HttpRequestInfo request1;
12779 request1.method = "GET";
12780 request1.url = GURL("https://www.a.com/");
12781 request1.load_flags = 0;
12782 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012783 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312784
12785 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
12786 EXPECT_EQ(ERR_IO_PENDING, rv);
12787 EXPECT_EQ(OK, callback.WaitForResult());
12788
12789 const HttpResponseInfo* response = trans->GetResponseInfo();
12790 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012791 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312792 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12793 EXPECT_TRUE(response->was_fetched_via_spdy);
12794 EXPECT_TRUE(response->was_npn_negotiated);
12795
12796 std::string response_data;
12797 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12798 EXPECT_EQ("hello!", response_data);
12799 trans.reset();
12800 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612801 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312802
12803 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4012804 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5312805 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312806 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612807 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312808 HttpRequestInfo request2;
12809 request2.method = "GET";
12810 request2.url = GURL("https://www.b.com/");
12811 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012812 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312813
12814 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
12815 EXPECT_EQ(ERR_IO_PENDING, rv);
12816 EXPECT_EQ(OK, callback.WaitForResult());
12817
12818 response = trans->GetResponseInfo();
12819 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012820 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312821 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12822 EXPECT_TRUE(response->was_fetched_via_spdy);
12823 EXPECT_TRUE(response->was_npn_negotiated);
12824 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12825 EXPECT_EQ("hello!", response_data);
12826 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612827 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312828 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612829 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312830
12831 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4012832 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5312833 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312834 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612835 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0312836 HttpRequestInfo request3;
12837 request3.method = "GET";
12838 request3.url = GURL("http://www.a.com/");
12839 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012840 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312841
12842 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
12843 EXPECT_EQ(ERR_IO_PENDING, rv);
12844 EXPECT_EQ(OK, callback.WaitForResult());
12845
12846 response = trans->GetResponseInfo();
12847 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012848 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312849 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12850 EXPECT_FALSE(response->was_fetched_via_spdy);
12851 EXPECT_FALSE(response->was_npn_negotiated);
12852 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12853 EXPECT_EQ("hello!", response_data);
12854 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612855 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312856 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612857 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312858}
12859
[email protected]79e1fd62013-06-20 06:50:0412860TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
12861 HttpRequestInfo request;
12862 request.method = "GET";
bncce36dca22015-04-21 22:11:2312863 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412864 request.load_flags = 0;
12865
[email protected]3fe8d2f82013-10-17 08:56:0712866 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412867 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412869
12870 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
12871 StaticSocketDataProvider data;
12872 data.set_connect_data(mock_connect);
12873 session_deps_.socket_factory->AddSocketDataProvider(&data);
12874
12875 TestCompletionCallback callback;
12876
12877 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12878 EXPECT_EQ(ERR_IO_PENDING, rv);
12879
12880 rv = callback.WaitForResult();
12881 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12882
[email protected]79e1fd62013-06-20 06:50:0412883 // We don't care whether this succeeds or fails, but it shouldn't crash.
12884 HttpRequestHeaders request_headers;
12885 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712886
12887 ConnectionAttempts attempts;
12888 trans->GetConnectionAttempts(&attempts);
12889 ASSERT_EQ(1u, attempts.size());
12890 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412891}
12892
12893TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
12894 HttpRequestInfo request;
12895 request.method = "GET";
bncce36dca22015-04-21 22:11:2312896 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412897 request.load_flags = 0;
12898
[email protected]3fe8d2f82013-10-17 08:56:0712899 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412900 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112901 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412902
12903 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12904 StaticSocketDataProvider data;
12905 data.set_connect_data(mock_connect);
12906 session_deps_.socket_factory->AddSocketDataProvider(&data);
12907
12908 TestCompletionCallback callback;
12909
12910 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12911 EXPECT_EQ(ERR_IO_PENDING, rv);
12912
12913 rv = callback.WaitForResult();
12914 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12915
[email protected]79e1fd62013-06-20 06:50:0412916 // We don't care whether this succeeds or fails, but it shouldn't crash.
12917 HttpRequestHeaders request_headers;
12918 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712919
12920 ConnectionAttempts attempts;
12921 trans->GetConnectionAttempts(&attempts);
12922 ASSERT_EQ(1u, attempts.size());
12923 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412924}
12925
12926TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12927 HttpRequestInfo request;
12928 request.method = "GET";
bncce36dca22015-04-21 22:11:2312929 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412930 request.load_flags = 0;
12931
[email protected]3fe8d2f82013-10-17 08:56:0712932 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412933 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112934 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412935
12936 MockWrite data_writes[] = {
12937 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12938 };
12939 MockRead data_reads[] = {
12940 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12941 };
12942
12943 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12944 data_writes, arraysize(data_writes));
12945 session_deps_.socket_factory->AddSocketDataProvider(&data);
12946
12947 TestCompletionCallback callback;
12948
12949 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12950 EXPECT_EQ(ERR_IO_PENDING, rv);
12951
12952 rv = callback.WaitForResult();
12953 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12954
[email protected]79e1fd62013-06-20 06:50:0412955 HttpRequestHeaders request_headers;
12956 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12957 EXPECT_TRUE(request_headers.HasHeader("Host"));
12958}
12959
12960TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12961 HttpRequestInfo request;
12962 request.method = "GET";
bncce36dca22015-04-21 22:11:2312963 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412964 request.load_flags = 0;
12965
[email protected]3fe8d2f82013-10-17 08:56:0712966 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412967 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112968 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412969
12970 MockWrite data_writes[] = {
12971 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12972 };
12973 MockRead data_reads[] = {
12974 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12975 };
12976
12977 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12978 data_writes, arraysize(data_writes));
12979 session_deps_.socket_factory->AddSocketDataProvider(&data);
12980
12981 TestCompletionCallback callback;
12982
12983 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12984 EXPECT_EQ(ERR_IO_PENDING, rv);
12985
12986 rv = callback.WaitForResult();
12987 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12988
[email protected]79e1fd62013-06-20 06:50:0412989 HttpRequestHeaders request_headers;
12990 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12991 EXPECT_TRUE(request_headers.HasHeader("Host"));
12992}
12993
12994TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12995 HttpRequestInfo request;
12996 request.method = "GET";
bncce36dca22015-04-21 22:11:2312997 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412998 request.load_flags = 0;
12999
[email protected]3fe8d2f82013-10-17 08:56:0713000 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413001 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113002 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413003
13004 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313005 MockWrite(
13006 "GET / HTTP/1.1\r\n"
13007 "Host: www.example.org\r\n"
13008 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413009 };
13010 MockRead data_reads[] = {
13011 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
13012 };
13013
13014 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13015 data_writes, arraysize(data_writes));
13016 session_deps_.socket_factory->AddSocketDataProvider(&data);
13017
13018 TestCompletionCallback callback;
13019
13020 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13021 EXPECT_EQ(ERR_IO_PENDING, rv);
13022
13023 rv = callback.WaitForResult();
13024 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13025
[email protected]79e1fd62013-06-20 06:50:0413026 HttpRequestHeaders request_headers;
13027 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13028 EXPECT_TRUE(request_headers.HasHeader("Host"));
13029}
13030
13031TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
13032 HttpRequestInfo request;
13033 request.method = "GET";
bncce36dca22015-04-21 22:11:2313034 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413035 request.load_flags = 0;
13036
[email protected]3fe8d2f82013-10-17 08:56:0713037 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413038 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113039 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413040
13041 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313042 MockWrite(
13043 "GET / HTTP/1.1\r\n"
13044 "Host: www.example.org\r\n"
13045 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413046 };
13047 MockRead data_reads[] = {
13048 MockRead(ASYNC, ERR_CONNECTION_RESET),
13049 };
13050
13051 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13052 data_writes, arraysize(data_writes));
13053 session_deps_.socket_factory->AddSocketDataProvider(&data);
13054
13055 TestCompletionCallback callback;
13056
13057 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13058 EXPECT_EQ(ERR_IO_PENDING, rv);
13059
13060 rv = callback.WaitForResult();
13061 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13062
[email protected]79e1fd62013-06-20 06:50:0413063 HttpRequestHeaders request_headers;
13064 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13065 EXPECT_TRUE(request_headers.HasHeader("Host"));
13066}
13067
13068TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
13069 HttpRequestInfo request;
13070 request.method = "GET";
bncce36dca22015-04-21 22:11:2313071 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413072 request.load_flags = 0;
13073 request.extra_headers.SetHeader("X-Foo", "bar");
13074
[email protected]3fe8d2f82013-10-17 08:56:0713075 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413076 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113077 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413078
13079 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313080 MockWrite(
13081 "GET / HTTP/1.1\r\n"
13082 "Host: www.example.org\r\n"
13083 "Connection: keep-alive\r\n"
13084 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413085 };
13086 MockRead data_reads[] = {
13087 MockRead("HTTP/1.1 200 OK\r\n"
13088 "Content-Length: 5\r\n\r\n"
13089 "hello"),
13090 MockRead(ASYNC, ERR_UNEXPECTED),
13091 };
13092
13093 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13094 data_writes, arraysize(data_writes));
13095 session_deps_.socket_factory->AddSocketDataProvider(&data);
13096
13097 TestCompletionCallback callback;
13098
13099 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13100 EXPECT_EQ(ERR_IO_PENDING, rv);
13101
13102 rv = callback.WaitForResult();
13103 EXPECT_EQ(OK, rv);
13104
13105 HttpRequestHeaders request_headers;
13106 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13107 std::string foo;
13108 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
13109 EXPECT_EQ("bar", foo);
13110}
13111
[email protected]bf828982013-08-14 18:01:4713112namespace {
13113
yhiranoa7e05bb2014-11-06 05:40:3913114// Fake HttpStream that simply records calls to SetPriority().
13115class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0313116 public base::SupportsWeakPtr<FakeStream> {
13117 public:
13118 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2013119 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0313120
13121 RequestPriority priority() const { return priority_; }
13122
dchengb03027d2014-10-21 12:00:2013123 int InitializeStream(const HttpRequestInfo* request_info,
13124 RequestPriority priority,
13125 const BoundNetLog& net_log,
13126 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313127 return ERR_IO_PENDING;
13128 }
13129
dchengb03027d2014-10-21 12:00:2013130 int SendRequest(const HttpRequestHeaders& request_headers,
13131 HttpResponseInfo* response,
13132 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313133 ADD_FAILURE();
13134 return ERR_UNEXPECTED;
13135 }
13136
dchengb03027d2014-10-21 12:00:2013137 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313138 ADD_FAILURE();
13139 return ERR_UNEXPECTED;
13140 }
13141
dchengb03027d2014-10-21 12:00:2013142 int ReadResponseBody(IOBuffer* buf,
13143 int buf_len,
13144 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313145 ADD_FAILURE();
13146 return ERR_UNEXPECTED;
13147 }
13148
dchengb03027d2014-10-21 12:00:2013149 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0313150
dchengb03027d2014-10-21 12:00:2013151 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0313152 ADD_FAILURE();
13153 return false;
13154 }
13155
dchengb03027d2014-10-21 12:00:2013156 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0313157
dchengb03027d2014-10-21 12:00:2013158 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0313159 ADD_FAILURE();
13160 return false;
13161 }
13162
dchengb03027d2014-10-21 12:00:2013163 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313164
dchengb03027d2014-10-21 12:00:2013165 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0313166 ADD_FAILURE();
13167 return false;
13168 }
13169
dchengb03027d2014-10-21 12:00:2013170 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5913171 ADD_FAILURE();
13172 return 0;
13173 }
13174
dchengb03027d2014-10-21 12:00:2013175 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0313176 ADD_FAILURE();
13177 return false;
13178 }
13179
dchengb03027d2014-10-21 12:00:2013180 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
13181
13182 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0313183 ADD_FAILURE();
13184 }
13185
dchengb03027d2014-10-21 12:00:2013186 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0313187 ADD_FAILURE();
13188 return false;
13189 }
13190
dchengb03027d2014-10-21 12:00:2013191 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313192
dchengb03027d2014-10-21 12:00:2013193 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0313194
yhiranoa7e05bb2014-11-06 05:40:3913195 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
13196
13197 HttpStream* RenewStreamForAuth() override { return NULL; }
13198
[email protected]e86839fd2013-08-14 18:29:0313199 private:
13200 RequestPriority priority_;
13201
13202 DISALLOW_COPY_AND_ASSIGN(FakeStream);
13203};
13204
13205// Fake HttpStreamRequest that simply records calls to SetPriority()
13206// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4713207class FakeStreamRequest : public HttpStreamRequest,
13208 public base::SupportsWeakPtr<FakeStreamRequest> {
13209 public:
[email protected]e86839fd2013-08-14 18:29:0313210 FakeStreamRequest(RequestPriority priority,
13211 HttpStreamRequest::Delegate* delegate)
13212 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4413213 delegate_(delegate),
13214 websocket_stream_create_helper_(NULL) {}
13215
13216 FakeStreamRequest(RequestPriority priority,
13217 HttpStreamRequest::Delegate* delegate,
13218 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
13219 : priority_(priority),
13220 delegate_(delegate),
13221 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0313222
dchengb03027d2014-10-21 12:00:2013223 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4713224
13225 RequestPriority priority() const { return priority_; }
13226
[email protected]831e4a32013-11-14 02:14:4413227 const WebSocketHandshakeStreamBase::CreateHelper*
13228 websocket_stream_create_helper() const {
13229 return websocket_stream_create_helper_;
13230 }
13231
[email protected]e86839fd2013-08-14 18:29:0313232 // Create a new FakeStream and pass it to the request's
13233 // delegate. Returns a weak pointer to the FakeStream.
13234 base::WeakPtr<FakeStream> FinishStreamRequest() {
13235 FakeStream* fake_stream = new FakeStream(priority_);
13236 // Do this before calling OnStreamReady() as OnStreamReady() may
13237 // immediately delete |fake_stream|.
13238 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
13239 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
13240 return weak_stream;
13241 }
13242
dchengb03027d2014-10-21 12:00:2013243 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4713244 ADD_FAILURE();
13245 return ERR_UNEXPECTED;
13246 }
13247
dchengb03027d2014-10-21 12:00:2013248 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4713249 ADD_FAILURE();
13250 return LoadState();
13251 }
13252
dchengb03027d2014-10-21 12:00:2013253 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4713254
dchengb03027d2014-10-21 12:00:2013255 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713256
dchengb03027d2014-10-21 12:00:2013257 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4713258
dchengb03027d2014-10-21 12:00:2013259 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713260
ttuttle1f2d7e92015-04-28 16:17:4713261 const ConnectionAttempts& connection_attempts() const override {
13262 static ConnectionAttempts no_attempts;
13263 return no_attempts;
13264 }
13265
[email protected]bf828982013-08-14 18:01:4713266 private:
13267 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0313268 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4413269 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4713270
13271 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
13272};
13273
13274// Fake HttpStreamFactory that vends FakeStreamRequests.
13275class FakeStreamFactory : public HttpStreamFactory {
13276 public:
13277 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2013278 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4713279
13280 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
13281 // RequestStream() (which may be NULL if it was destroyed already).
13282 base::WeakPtr<FakeStreamRequest> last_stream_request() {
13283 return last_stream_request_;
13284 }
13285
dchengb03027d2014-10-21 12:00:2013286 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
13287 RequestPriority priority,
13288 const SSLConfig& server_ssl_config,
13289 const SSLConfig& proxy_ssl_config,
13290 HttpStreamRequest::Delegate* delegate,
13291 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0313292 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4713293 last_stream_request_ = fake_request->AsWeakPtr();
13294 return fake_request;
13295 }
13296
dchengb03027d2014-10-21 12:00:2013297 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4713298 const HttpRequestInfo& info,
13299 RequestPriority priority,
13300 const SSLConfig& server_ssl_config,
13301 const SSLConfig& proxy_ssl_config,
13302 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4613303 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1313304 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4413305 FakeStreamRequest* fake_request =
13306 new FakeStreamRequest(priority, delegate, create_helper);
13307 last_stream_request_ = fake_request->AsWeakPtr();
13308 return fake_request;
[email protected]bf828982013-08-14 18:01:4713309 }
13310
dchengb03027d2014-10-21 12:00:2013311 void PreconnectStreams(int num_streams,
13312 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2013313 const SSLConfig& server_ssl_config,
13314 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4713315 ADD_FAILURE();
13316 }
13317
dchengb03027d2014-10-21 12:00:2013318 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4713319 ADD_FAILURE();
13320 return NULL;
13321 }
13322
13323 private:
13324 base::WeakPtr<FakeStreamRequest> last_stream_request_;
13325
13326 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
13327};
13328
Adam Rice425cf122015-01-19 06:18:2413329// TODO(ricea): Maybe unify this with the one in
13330// url_request_http_job_unittest.cc ?
13331class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
13332 public:
13333 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
13334 bool using_proxy)
13335 : state_(connection.release(), using_proxy) {}
13336
13337 // Fake implementation of HttpStreamBase methods.
13338 // This ends up being quite "real" because this object has to really send data
13339 // on the mock socket. It might be easier to use the real implementation, but
13340 // the fact that the WebSocket code is not compiled on iOS makes that
13341 // difficult.
13342 int InitializeStream(const HttpRequestInfo* request_info,
13343 RequestPriority priority,
13344 const BoundNetLog& net_log,
13345 const CompletionCallback& callback) override {
13346 state_.Initialize(request_info, priority, net_log, callback);
13347 return OK;
13348 }
13349
13350 int SendRequest(const HttpRequestHeaders& request_headers,
13351 HttpResponseInfo* response,
13352 const CompletionCallback& callback) override {
13353 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
13354 response, callback);
13355 }
13356
13357 int ReadResponseHeaders(const CompletionCallback& callback) override {
13358 return parser()->ReadResponseHeaders(callback);
13359 }
13360
13361 int ReadResponseBody(IOBuffer* buf,
13362 int buf_len,
13363 const CompletionCallback& callback) override {
13364 NOTREACHED();
13365 return ERR_IO_PENDING;
13366 }
13367
13368 void Close(bool not_reusable) override {
13369 if (parser())
13370 parser()->Close(true);
13371 }
13372
13373 bool IsResponseBodyComplete() const override {
13374 NOTREACHED();
13375 return false;
13376 }
13377
13378 bool CanFindEndOfResponse() const override {
13379 return parser()->CanFindEndOfResponse();
13380 }
13381
13382 bool IsConnectionReused() const override {
13383 NOTREACHED();
13384 return false;
13385 }
13386 void SetConnectionReused() override { NOTREACHED(); }
13387
13388 bool IsConnectionReusable() const override {
13389 NOTREACHED();
13390 return false;
13391 }
13392
13393 int64 GetTotalReceivedBytes() const override {
13394 NOTREACHED();
13395 return 0;
13396 }
13397
13398 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13399 NOTREACHED();
13400 return false;
13401 }
13402
Adam Ricecb76ac62015-02-20 05:33:2513403 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413404
13405 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13406 NOTREACHED();
13407 }
13408
13409 bool IsSpdyHttpStream() const override {
13410 NOTREACHED();
13411 return false;
13412 }
13413
13414 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13415
13416 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13417
13418 UploadProgress GetUploadProgress() const override {
13419 NOTREACHED();
13420 return UploadProgress();
13421 }
13422
13423 HttpStream* RenewStreamForAuth() override {
13424 NOTREACHED();
13425 return nullptr;
13426 }
13427
13428 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13429 scoped_ptr<WebSocketStream> Upgrade() override {
13430 NOTREACHED();
13431 return scoped_ptr<WebSocketStream>();
13432 }
13433
13434 private:
13435 HttpStreamParser* parser() const { return state_.parser(); }
13436 HttpBasicState state_;
13437
13438 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13439};
13440
[email protected]831e4a32013-11-14 02:14:4413441// TODO(yhirano): Split this class out into a net/websockets file, if it is
13442// worth doing.
13443class FakeWebSocketStreamCreateHelper :
13444 public WebSocketHandshakeStreamBase::CreateHelper {
13445 public:
dchengb03027d2014-10-21 12:00:2013446 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113447 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313448 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413449 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13450 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413451 }
13452
dchengb03027d2014-10-21 12:00:2013453 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413454 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313455 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413456 NOTREACHED();
13457 return NULL;
13458 };
13459
dchengb03027d2014-10-21 12:00:2013460 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413461
13462 virtual scoped_ptr<WebSocketStream> Upgrade() {
13463 NOTREACHED();
13464 return scoped_ptr<WebSocketStream>();
13465 }
13466};
13467
[email protected]bf828982013-08-14 18:01:4713468} // namespace
13469
13470// Make sure that HttpNetworkTransaction passes on its priority to its
13471// stream request on start.
13472TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
13473 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13474 HttpNetworkSessionPeer peer(session);
13475 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413476 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713477
dcheng48459ac22014-08-26 00:46:4113478 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713479
13480 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13481
13482 HttpRequestInfo request;
13483 TestCompletionCallback callback;
13484 EXPECT_EQ(ERR_IO_PENDING,
13485 trans.Start(&request, callback.callback(), BoundNetLog()));
13486
13487 base::WeakPtr<FakeStreamRequest> fake_request =
13488 fake_factory->last_stream_request();
13489 ASSERT_TRUE(fake_request != NULL);
13490 EXPECT_EQ(LOW, fake_request->priority());
13491}
13492
13493// Make sure that HttpNetworkTransaction passes on its priority
13494// updates to its stream request.
13495TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
13496 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13497 HttpNetworkSessionPeer peer(session);
13498 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413499 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713500
dcheng48459ac22014-08-26 00:46:4113501 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713502
13503 HttpRequestInfo request;
13504 TestCompletionCallback callback;
13505 EXPECT_EQ(ERR_IO_PENDING,
13506 trans.Start(&request, callback.callback(), BoundNetLog()));
13507
13508 base::WeakPtr<FakeStreamRequest> fake_request =
13509 fake_factory->last_stream_request();
13510 ASSERT_TRUE(fake_request != NULL);
13511 EXPECT_EQ(LOW, fake_request->priority());
13512
13513 trans.SetPriority(LOWEST);
13514 ASSERT_TRUE(fake_request != NULL);
13515 EXPECT_EQ(LOWEST, fake_request->priority());
13516}
13517
[email protected]e86839fd2013-08-14 18:29:0313518// Make sure that HttpNetworkTransaction passes on its priority
13519// updates to its stream.
13520TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
13521 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13522 HttpNetworkSessionPeer peer(session);
13523 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413524 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313525
dcheng48459ac22014-08-26 00:46:4113526 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313527
13528 HttpRequestInfo request;
13529 TestCompletionCallback callback;
13530 EXPECT_EQ(ERR_IO_PENDING,
13531 trans.Start(&request, callback.callback(), BoundNetLog()));
13532
13533 base::WeakPtr<FakeStreamRequest> fake_request =
13534 fake_factory->last_stream_request();
13535 ASSERT_TRUE(fake_request != NULL);
13536 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13537 ASSERT_TRUE(fake_stream != NULL);
13538 EXPECT_EQ(LOW, fake_stream->priority());
13539
13540 trans.SetPriority(LOWEST);
13541 EXPECT_EQ(LOWEST, fake_stream->priority());
13542}
13543
[email protected]831e4a32013-11-14 02:14:4413544TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13545 // The same logic needs to be tested for both ws: and wss: schemes, but this
13546 // test is already parameterised on NextProto, so it uses a loop to verify
13547 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313548 std::string test_cases[] = {"ws://www.example.org/",
13549 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413550 for (size_t i = 0; i < arraysize(test_cases); ++i) {
13551 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13552 HttpNetworkSessionPeer peer(session);
13553 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13554 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313555 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413556 scoped_ptr<HttpStreamFactory>(fake_factory));
13557
dcheng48459ac22014-08-26 00:46:4113558 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413559 trans.SetWebSocketHandshakeStreamCreateHelper(
13560 &websocket_stream_create_helper);
13561
13562 HttpRequestInfo request;
13563 TestCompletionCallback callback;
13564 request.method = "GET";
13565 request.url = GURL(test_cases[i]);
13566
13567 EXPECT_EQ(ERR_IO_PENDING,
13568 trans.Start(&request, callback.callback(), BoundNetLog()));
13569
13570 base::WeakPtr<FakeStreamRequest> fake_request =
13571 fake_factory->last_stream_request();
13572 ASSERT_TRUE(fake_request != NULL);
13573 EXPECT_EQ(&websocket_stream_create_helper,
13574 fake_request->websocket_stream_create_helper());
13575 }
13576}
13577
[email protected]043b68c82013-08-22 23:41:5213578// Tests that when a used socket is returned to the SSL socket pool, it's closed
13579// if the transport socket pool is stalled on the global socket limit.
13580TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13581 ClientSocketPoolManager::set_max_sockets_per_group(
13582 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13583 ClientSocketPoolManager::set_max_sockets_per_pool(
13584 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13585
13586 // Set up SSL request.
13587
13588 HttpRequestInfo ssl_request;
13589 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313590 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213591
13592 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313593 MockWrite(
13594 "GET / HTTP/1.1\r\n"
13595 "Host: www.example.org\r\n"
13596 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213597 };
13598 MockRead ssl_reads[] = {
13599 MockRead("HTTP/1.1 200 OK\r\n"),
13600 MockRead("Content-Length: 11\r\n\r\n"),
13601 MockRead("hello world"),
13602 MockRead(SYNCHRONOUS, OK),
13603 };
13604 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13605 ssl_writes, arraysize(ssl_writes));
13606 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13607
13608 SSLSocketDataProvider ssl(ASYNC, OK);
13609 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13610
13611 // Set up HTTP request.
13612
13613 HttpRequestInfo http_request;
13614 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313615 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213616
13617 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313618 MockWrite(
13619 "GET / HTTP/1.1\r\n"
13620 "Host: www.example.org\r\n"
13621 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213622 };
13623 MockRead http_reads[] = {
13624 MockRead("HTTP/1.1 200 OK\r\n"),
13625 MockRead("Content-Length: 7\r\n\r\n"),
13626 MockRead("falafel"),
13627 MockRead(SYNCHRONOUS, OK),
13628 };
13629 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13630 http_writes, arraysize(http_writes));
13631 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13632
13633 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13634
13635 // Start the SSL request.
13636 TestCompletionCallback ssl_callback;
13637 scoped_ptr<HttpTransaction> ssl_trans(
13638 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13639 ASSERT_EQ(ERR_IO_PENDING,
13640 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13641 BoundNetLog()));
13642
13643 // Start the HTTP request. Pool should stall.
13644 TestCompletionCallback http_callback;
13645 scoped_ptr<HttpTransaction> http_trans(
13646 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13647 ASSERT_EQ(ERR_IO_PENDING,
13648 http_trans->Start(&http_request, http_callback.callback(),
13649 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113650 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213651
13652 // Wait for response from SSL request.
13653 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13654 std::string response_data;
13655 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13656 EXPECT_EQ("hello world", response_data);
13657
13658 // The SSL socket should automatically be closed, so the HTTP request can
13659 // start.
dcheng48459ac22014-08-26 00:46:4113660 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13661 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213662
13663 // The HTTP request can now complete.
13664 ASSERT_EQ(OK, http_callback.WaitForResult());
13665 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13666 EXPECT_EQ("falafel", response_data);
13667
dcheng48459ac22014-08-26 00:46:4113668 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213669}
13670
13671// Tests that when a SSL connection is established but there's no corresponding
13672// request that needs it, the new socket is closed if the transport socket pool
13673// is stalled on the global socket limit.
13674TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13675 ClientSocketPoolManager::set_max_sockets_per_group(
13676 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13677 ClientSocketPoolManager::set_max_sockets_per_pool(
13678 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13679
13680 // Set up an ssl request.
13681
13682 HttpRequestInfo ssl_request;
13683 ssl_request.method = "GET";
13684 ssl_request.url = GURL("https://www.foopy.com/");
13685
13686 // No data will be sent on the SSL socket.
13687 StaticSocketDataProvider ssl_data;
13688 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13689
13690 SSLSocketDataProvider ssl(ASYNC, OK);
13691 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13692
13693 // Set up HTTP request.
13694
13695 HttpRequestInfo http_request;
13696 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313697 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213698
13699 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313700 MockWrite(
13701 "GET / HTTP/1.1\r\n"
13702 "Host: www.example.org\r\n"
13703 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213704 };
13705 MockRead http_reads[] = {
13706 MockRead("HTTP/1.1 200 OK\r\n"),
13707 MockRead("Content-Length: 7\r\n\r\n"),
13708 MockRead("falafel"),
13709 MockRead(SYNCHRONOUS, OK),
13710 };
13711 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13712 http_writes, arraysize(http_writes));
13713 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13714
13715 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13716
13717 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13718 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2913719 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13720 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5213721 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd3972015-07-15 22:26:3513722 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
13723 ssl_config);
dcheng48459ac22014-08-26 00:46:4113724 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213725
13726 // Start the HTTP request. Pool should stall.
13727 TestCompletionCallback http_callback;
13728 scoped_ptr<HttpTransaction> http_trans(
13729 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13730 ASSERT_EQ(ERR_IO_PENDING,
13731 http_trans->Start(&http_request, http_callback.callback(),
13732 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113733 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213734
13735 // The SSL connection will automatically be closed once the connection is
13736 // established, to let the HTTP request start.
13737 ASSERT_EQ(OK, http_callback.WaitForResult());
13738 std::string response_data;
13739 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13740 EXPECT_EQ("falafel", response_data);
13741
dcheng48459ac22014-08-26 00:46:4113742 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213743}
13744
[email protected]02d74a02014-04-23 18:10:5413745TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13746 ScopedVector<UploadElementReader> element_readers;
13747 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713748 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413749
13750 HttpRequestInfo request;
13751 request.method = "POST";
13752 request.url = GURL("http://www.foo.com/");
13753 request.upload_data_stream = &upload_data_stream;
13754 request.load_flags = 0;
13755
13756 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13757 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113758 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413759 // Send headers successfully, but get an error while sending the body.
13760 MockWrite data_writes[] = {
13761 MockWrite("POST / HTTP/1.1\r\n"
13762 "Host: www.foo.com\r\n"
13763 "Connection: keep-alive\r\n"
13764 "Content-Length: 3\r\n\r\n"),
13765 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13766 };
13767
13768 MockRead data_reads[] = {
13769 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13770 MockRead("hello world"),
13771 MockRead(SYNCHRONOUS, OK),
13772 };
13773 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13774 arraysize(data_writes));
13775 session_deps_.socket_factory->AddSocketDataProvider(&data);
13776
13777 TestCompletionCallback callback;
13778
13779 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13780 EXPECT_EQ(ERR_IO_PENDING, rv);
13781
13782 rv = callback.WaitForResult();
13783 EXPECT_EQ(OK, rv);
13784
13785 const HttpResponseInfo* response = trans->GetResponseInfo();
13786 ASSERT_TRUE(response != NULL);
13787
13788 EXPECT_TRUE(response->headers.get() != NULL);
13789 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13790
13791 std::string response_data;
13792 rv = ReadTransaction(trans.get(), &response_data);
13793 EXPECT_EQ(OK, rv);
13794 EXPECT_EQ("hello world", response_data);
13795}
13796
13797// This test makes sure the retry logic doesn't trigger when reading an error
13798// response from a server that rejected a POST with a CONNECTION_RESET.
13799TEST_P(HttpNetworkTransactionTest,
13800 PostReadsErrorResponseAfterResetOnReusedSocket) {
13801 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13802 MockWrite data_writes[] = {
13803 MockWrite("GET / HTTP/1.1\r\n"
13804 "Host: www.foo.com\r\n"
13805 "Connection: keep-alive\r\n\r\n"),
13806 MockWrite("POST / HTTP/1.1\r\n"
13807 "Host: www.foo.com\r\n"
13808 "Connection: keep-alive\r\n"
13809 "Content-Length: 3\r\n\r\n"),
13810 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13811 };
13812
13813 MockRead data_reads[] = {
13814 MockRead("HTTP/1.1 200 Peachy\r\n"
13815 "Content-Length: 14\r\n\r\n"),
13816 MockRead("first response"),
13817 MockRead("HTTP/1.1 400 Not OK\r\n"
13818 "Content-Length: 15\r\n\r\n"),
13819 MockRead("second response"),
13820 MockRead(SYNCHRONOUS, OK),
13821 };
13822 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13823 arraysize(data_writes));
13824 session_deps_.socket_factory->AddSocketDataProvider(&data);
13825
13826 TestCompletionCallback callback;
13827 HttpRequestInfo request1;
13828 request1.method = "GET";
13829 request1.url = GURL("http://www.foo.com/");
13830 request1.load_flags = 0;
13831
13832 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4113833 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413834 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
13835 EXPECT_EQ(ERR_IO_PENDING, rv);
13836
13837 rv = callback.WaitForResult();
13838 EXPECT_EQ(OK, rv);
13839
13840 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13841 ASSERT_TRUE(response1 != NULL);
13842
13843 EXPECT_TRUE(response1->headers.get() != NULL);
13844 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
13845
13846 std::string response_data1;
13847 rv = ReadTransaction(trans1.get(), &response_data1);
13848 EXPECT_EQ(OK, rv);
13849 EXPECT_EQ("first response", response_data1);
13850 // Delete the transaction to release the socket back into the socket pool.
13851 trans1.reset();
13852
13853 ScopedVector<UploadElementReader> element_readers;
13854 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713855 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413856
13857 HttpRequestInfo request2;
13858 request2.method = "POST";
13859 request2.url = GURL("http://www.foo.com/");
13860 request2.upload_data_stream = &upload_data_stream;
13861 request2.load_flags = 0;
13862
13863 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4113864 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413865 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
13866 EXPECT_EQ(ERR_IO_PENDING, rv);
13867
13868 rv = callback.WaitForResult();
13869 EXPECT_EQ(OK, rv);
13870
13871 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
13872 ASSERT_TRUE(response2 != NULL);
13873
13874 EXPECT_TRUE(response2->headers.get() != NULL);
13875 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
13876
13877 std::string response_data2;
13878 rv = ReadTransaction(trans2.get(), &response_data2);
13879 EXPECT_EQ(OK, rv);
13880 EXPECT_EQ("second response", response_data2);
13881}
13882
13883TEST_P(HttpNetworkTransactionTest,
13884 PostReadsErrorResponseAfterResetPartialBodySent) {
13885 ScopedVector<UploadElementReader> element_readers;
13886 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713887 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413888
13889 HttpRequestInfo request;
13890 request.method = "POST";
13891 request.url = GURL("http://www.foo.com/");
13892 request.upload_data_stream = &upload_data_stream;
13893 request.load_flags = 0;
13894
13895 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13896 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113897 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413898 // Send headers successfully, but get an error while sending the body.
13899 MockWrite data_writes[] = {
13900 MockWrite("POST / HTTP/1.1\r\n"
13901 "Host: www.foo.com\r\n"
13902 "Connection: keep-alive\r\n"
13903 "Content-Length: 3\r\n\r\n"
13904 "fo"),
13905 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13906 };
13907
13908 MockRead data_reads[] = {
13909 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13910 MockRead("hello world"),
13911 MockRead(SYNCHRONOUS, OK),
13912 };
13913 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13914 arraysize(data_writes));
13915 session_deps_.socket_factory->AddSocketDataProvider(&data);
13916
13917 TestCompletionCallback callback;
13918
13919 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13920 EXPECT_EQ(ERR_IO_PENDING, rv);
13921
13922 rv = callback.WaitForResult();
13923 EXPECT_EQ(OK, rv);
13924
13925 const HttpResponseInfo* response = trans->GetResponseInfo();
13926 ASSERT_TRUE(response != NULL);
13927
13928 EXPECT_TRUE(response->headers.get() != NULL);
13929 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13930
13931 std::string response_data;
13932 rv = ReadTransaction(trans.get(), &response_data);
13933 EXPECT_EQ(OK, rv);
13934 EXPECT_EQ("hello world", response_data);
13935}
13936
13937// This tests the more common case than the previous test, where headers and
13938// body are not merged into a single request.
13939TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
13940 ScopedVector<UploadElementReader> element_readers;
13941 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713942 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5413943
13944 HttpRequestInfo request;
13945 request.method = "POST";
13946 request.url = GURL("http://www.foo.com/");
13947 request.upload_data_stream = &upload_data_stream;
13948 request.load_flags = 0;
13949
13950 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13951 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113952 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413953 // Send headers successfully, but get an error while sending the body.
13954 MockWrite data_writes[] = {
13955 MockWrite("POST / HTTP/1.1\r\n"
13956 "Host: www.foo.com\r\n"
13957 "Connection: keep-alive\r\n"
13958 "Transfer-Encoding: chunked\r\n\r\n"),
13959 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13960 };
13961
13962 MockRead data_reads[] = {
13963 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13964 MockRead("hello world"),
13965 MockRead(SYNCHRONOUS, OK),
13966 };
13967 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13968 arraysize(data_writes));
13969 session_deps_.socket_factory->AddSocketDataProvider(&data);
13970
13971 TestCompletionCallback callback;
13972
13973 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13974 EXPECT_EQ(ERR_IO_PENDING, rv);
13975 // Make sure the headers are sent before adding a chunk. This ensures that
13976 // they can't be merged with the body in a single send. Not currently
13977 // necessary since a chunked body is never merged with headers, but this makes
13978 // the test more future proof.
13979 base::RunLoop().RunUntilIdle();
13980
mmenkecbc2b712014-10-09 20:29:0713981 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5413982
13983 rv = callback.WaitForResult();
13984 EXPECT_EQ(OK, rv);
13985
13986 const HttpResponseInfo* response = trans->GetResponseInfo();
13987 ASSERT_TRUE(response != NULL);
13988
13989 EXPECT_TRUE(response->headers.get() != NULL);
13990 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13991
13992 std::string response_data;
13993 rv = ReadTransaction(trans.get(), &response_data);
13994 EXPECT_EQ(OK, rv);
13995 EXPECT_EQ("hello world", response_data);
13996}
13997
13998TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
13999 ScopedVector<UploadElementReader> element_readers;
14000 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714001 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414002
14003 HttpRequestInfo request;
14004 request.method = "POST";
14005 request.url = GURL("http://www.foo.com/");
14006 request.upload_data_stream = &upload_data_stream;
14007 request.load_flags = 0;
14008
14009 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14010 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114011 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414012
14013 MockWrite data_writes[] = {
14014 MockWrite("POST / HTTP/1.1\r\n"
14015 "Host: www.foo.com\r\n"
14016 "Connection: keep-alive\r\n"
14017 "Content-Length: 3\r\n\r\n"),
14018 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14019 };
14020
14021 MockRead data_reads[] = {
14022 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14023 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14024 MockRead("hello world"),
14025 MockRead(SYNCHRONOUS, OK),
14026 };
14027 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14028 arraysize(data_writes));
14029 session_deps_.socket_factory->AddSocketDataProvider(&data);
14030
14031 TestCompletionCallback callback;
14032
14033 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14034 EXPECT_EQ(ERR_IO_PENDING, rv);
14035
14036 rv = callback.WaitForResult();
14037 EXPECT_EQ(OK, rv);
14038
14039 const HttpResponseInfo* response = trans->GetResponseInfo();
14040 ASSERT_TRUE(response != NULL);
14041
14042 EXPECT_TRUE(response->headers.get() != NULL);
14043 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14044
14045 std::string response_data;
14046 rv = ReadTransaction(trans.get(), &response_data);
14047 EXPECT_EQ(OK, rv);
14048 EXPECT_EQ("hello world", response_data);
14049}
14050
14051TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
14052 ScopedVector<UploadElementReader> element_readers;
14053 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714054 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414055
14056 HttpRequestInfo request;
14057 request.method = "POST";
14058 request.url = GURL("http://www.foo.com/");
14059 request.upload_data_stream = &upload_data_stream;
14060 request.load_flags = 0;
14061
14062 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14063 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114064 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414065 // Send headers successfully, but get an error while sending the body.
14066 MockWrite data_writes[] = {
14067 MockWrite("POST / HTTP/1.1\r\n"
14068 "Host: www.foo.com\r\n"
14069 "Connection: keep-alive\r\n"
14070 "Content-Length: 3\r\n\r\n"),
14071 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14072 };
14073
14074 MockRead data_reads[] = {
14075 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
14076 MockRead("hello world"),
14077 MockRead(SYNCHRONOUS, OK),
14078 };
14079 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14080 arraysize(data_writes));
14081 session_deps_.socket_factory->AddSocketDataProvider(&data);
14082
14083 TestCompletionCallback callback;
14084
14085 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14086 EXPECT_EQ(ERR_IO_PENDING, rv);
14087
14088 rv = callback.WaitForResult();
14089 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414090}
14091
14092TEST_P(HttpNetworkTransactionTest,
14093 PostIgnoresNonErrorResponseAfterResetAnd100) {
14094 ScopedVector<UploadElementReader> element_readers;
14095 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714096 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414097
14098 HttpRequestInfo request;
14099 request.method = "POST";
14100 request.url = GURL("http://www.foo.com/");
14101 request.upload_data_stream = &upload_data_stream;
14102 request.load_flags = 0;
14103
14104 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14105 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114106 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414107 // Send headers successfully, but get an error while sending the body.
14108 MockWrite data_writes[] = {
14109 MockWrite("POST / HTTP/1.1\r\n"
14110 "Host: www.foo.com\r\n"
14111 "Connection: keep-alive\r\n"
14112 "Content-Length: 3\r\n\r\n"),
14113 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14114 };
14115
14116 MockRead data_reads[] = {
14117 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14118 MockRead("HTTP/1.0 302 Redirect\r\n"),
14119 MockRead("Location: http://somewhere-else.com/\r\n"),
14120 MockRead("Content-Length: 0\r\n\r\n"),
14121 MockRead(SYNCHRONOUS, OK),
14122 };
14123 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14124 arraysize(data_writes));
14125 session_deps_.socket_factory->AddSocketDataProvider(&data);
14126
14127 TestCompletionCallback callback;
14128
14129 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14130 EXPECT_EQ(ERR_IO_PENDING, rv);
14131
14132 rv = callback.WaitForResult();
14133 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414134}
14135
14136TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
14137 ScopedVector<UploadElementReader> element_readers;
14138 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714139 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414140
14141 HttpRequestInfo request;
14142 request.method = "POST";
14143 request.url = GURL("http://www.foo.com/");
14144 request.upload_data_stream = &upload_data_stream;
14145 request.load_flags = 0;
14146
14147 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14148 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114149 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414150 // Send headers successfully, but get an error while sending the body.
14151 MockWrite data_writes[] = {
14152 MockWrite("POST / HTTP/1.1\r\n"
14153 "Host: www.foo.com\r\n"
14154 "Connection: keep-alive\r\n"
14155 "Content-Length: 3\r\n\r\n"),
14156 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14157 };
14158
14159 MockRead data_reads[] = {
14160 MockRead("HTTP 0.9 rocks!"),
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
14172 rv = callback.WaitForResult();
14173 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414174}
14175
14176TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
14177 ScopedVector<UploadElementReader> element_readers;
14178 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714179 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414180
14181 HttpRequestInfo request;
14182 request.method = "POST";
14183 request.url = GURL("http://www.foo.com/");
14184 request.upload_data_stream = &upload_data_stream;
14185 request.load_flags = 0;
14186
14187 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14188 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114189 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414190 // Send headers successfully, but get an error while sending the body.
14191 MockWrite data_writes[] = {
14192 MockWrite("POST / HTTP/1.1\r\n"
14193 "Host: www.foo.com\r\n"
14194 "Connection: keep-alive\r\n"
14195 "Content-Length: 3\r\n\r\n"),
14196 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14197 };
14198
14199 MockRead data_reads[] = {
14200 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
14201 MockRead(SYNCHRONOUS, OK),
14202 };
14203 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14204 arraysize(data_writes));
14205 session_deps_.socket_factory->AddSocketDataProvider(&data);
14206
14207 TestCompletionCallback callback;
14208
14209 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14210 EXPECT_EQ(ERR_IO_PENDING, rv);
14211
14212 rv = callback.WaitForResult();
14213 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414214}
14215
Adam Rice425cf122015-01-19 06:18:2414216// Verify that proxy headers are not sent to the destination server when
14217// establishing a tunnel for a secure WebSocket connection.
14218TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
14219 HttpRequestInfo request;
14220 request.method = "GET";
bncce36dca22015-04-21 22:11:2314221 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414222 AddWebSocketHeaders(&request.extra_headers);
14223
14224 // Configure against proxy server "myproxy:70".
14225 session_deps_.proxy_service.reset(
14226 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14227
14228 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14229
14230 // Since a proxy is configured, try to establish a tunnel.
14231 MockWrite data_writes[] = {
14232 MockWrite(
bncce36dca22015-04-21 22:11:2314233 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14234 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414235 "Proxy-Connection: keep-alive\r\n\r\n"),
14236
14237 // After calling trans->RestartWithAuth(), this is the request we should
14238 // be issuing -- the final header line contains the credentials.
14239 MockWrite(
bncce36dca22015-04-21 22:11:2314240 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14241 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414242 "Proxy-Connection: keep-alive\r\n"
14243 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14244
14245 MockWrite(
14246 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314247 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414248 "Connection: Upgrade\r\n"
14249 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314250 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414251 "Sec-WebSocket-Version: 13\r\n"
14252 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14253 };
14254
14255 // The proxy responds to the connect with a 407, using a persistent
14256 // connection.
14257 MockRead data_reads[] = {
14258 // No credentials.
14259 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14260 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
14261 MockRead("Proxy-Connection: close\r\n\r\n"),
14262
14263 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14264
14265 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14266 MockRead("Upgrade: websocket\r\n"),
14267 MockRead("Connection: Upgrade\r\n"),
14268 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14269 };
14270
14271 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14272 arraysize(data_writes));
14273 session_deps_.socket_factory->AddSocketDataProvider(&data);
14274 SSLSocketDataProvider ssl(ASYNC, OK);
14275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14276
14277 scoped_ptr<HttpTransaction> trans(
14278 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14279 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14280 trans->SetWebSocketHandshakeStreamCreateHelper(
14281 &websocket_stream_create_helper);
14282
14283 {
14284 TestCompletionCallback callback;
14285
14286 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14287 EXPECT_EQ(ERR_IO_PENDING, rv);
14288
14289 rv = callback.WaitForResult();
14290 EXPECT_EQ(OK, rv);
14291 }
14292
14293 const HttpResponseInfo* response = trans->GetResponseInfo();
14294 ASSERT_TRUE(response);
14295 ASSERT_TRUE(response->headers.get());
14296 EXPECT_EQ(407, response->headers->response_code());
14297
14298 {
14299 TestCompletionCallback callback;
14300
14301 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
14302 callback.callback());
14303 EXPECT_EQ(ERR_IO_PENDING, rv);
14304
14305 rv = callback.WaitForResult();
14306 EXPECT_EQ(OK, rv);
14307 }
14308
14309 response = trans->GetResponseInfo();
14310 ASSERT_TRUE(response);
14311 ASSERT_TRUE(response->headers.get());
14312
14313 EXPECT_EQ(101, response->headers->response_code());
14314
14315 trans.reset();
14316 session->CloseAllConnections();
14317}
14318
14319// Verify that proxy headers are not sent to the destination server when
14320// establishing a tunnel for an insecure WebSocket connection.
14321// This requires the authentication info to be injected into the auth cache
14322// due to crbug.com/395064
14323// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
14324TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
14325 HttpRequestInfo request;
14326 request.method = "GET";
bncce36dca22015-04-21 22:11:2314327 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414328 AddWebSocketHeaders(&request.extra_headers);
14329
14330 // Configure against proxy server "myproxy:70".
14331 session_deps_.proxy_service.reset(
14332 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14333
14334 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14335
14336 MockWrite data_writes[] = {
14337 // Try to establish a tunnel for the WebSocket connection, with
14338 // credentials. Because WebSockets have a separate set of socket pools,
14339 // they cannot and will not use the same TCP/IP connection as the
14340 // preflight HTTP request.
14341 MockWrite(
bncce36dca22015-04-21 22:11:2314342 "CONNECT www.example.org:80 HTTP/1.1\r\n"
14343 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2414344 "Proxy-Connection: keep-alive\r\n"
14345 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14346
14347 MockWrite(
14348 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314349 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414350 "Connection: Upgrade\r\n"
14351 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314352 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414353 "Sec-WebSocket-Version: 13\r\n"
14354 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14355 };
14356
14357 MockRead data_reads[] = {
14358 // HTTP CONNECT with credentials.
14359 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14360
14361 // WebSocket connection established inside tunnel.
14362 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14363 MockRead("Upgrade: websocket\r\n"),
14364 MockRead("Connection: Upgrade\r\n"),
14365 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14366 };
14367
14368 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14369 arraysize(data_writes));
14370 session_deps_.socket_factory->AddSocketDataProvider(&data);
14371
14372 session->http_auth_cache()->Add(
14373 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
14374 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
14375
14376 scoped_ptr<HttpTransaction> trans(
14377 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14378 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14379 trans->SetWebSocketHandshakeStreamCreateHelper(
14380 &websocket_stream_create_helper);
14381
14382 TestCompletionCallback callback;
14383
14384 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14385 EXPECT_EQ(ERR_IO_PENDING, rv);
14386
14387 rv = callback.WaitForResult();
14388 EXPECT_EQ(OK, rv);
14389
14390 const HttpResponseInfo* response = trans->GetResponseInfo();
14391 ASSERT_TRUE(response);
14392 ASSERT_TRUE(response->headers.get());
14393
14394 EXPECT_EQ(101, response->headers->response_code());
14395
14396 trans.reset();
14397 session->CloseAllConnections();
14398}
14399
[email protected]89ceba9a2009-03-21 03:46:0614400} // namespace net