blob: f05bcdc1dc57a0dcd432fa059c33896d4720d527 [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
[email protected]8a0fc822013-06-27 20:52:43291 // This is the expected return from a current server advertising SPDY.
292 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38293 return std::string("Alternate-Protocol: 443:") +
294 GetAlternateProtocolFromParam() + "\r\n\r\n";
[email protected]8a0fc822013-06-27 20:52:43295 }
296
[email protected]202965992011-12-07 23:04:51297 // Either |write_failure| specifies a write failure or |read_failure|
298 // specifies a read failure when using a reused socket. In either case, the
299 // failure should cause the network transaction to resend the request, and the
300 // other argument should be NULL.
301 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
302 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52303
[email protected]a34f61ee2014-03-18 20:59:49304 // Either |write_failure| specifies a write failure or |read_failure|
305 // specifies a read failure when using a reused socket. In either case, the
306 // failure should cause the network transaction to resend the request, and the
307 // other argument should be NULL.
308 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10309 const MockRead* read_failure,
310 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49311
[email protected]5a60c8b2011-10-19 20:14:29312 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
313 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15314 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52315
[email protected]ff007e162009-05-23 09:13:15316 HttpRequestInfo request;
317 request.method = "GET";
bncce36dca22015-04-21 22:11:23318 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15319 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52320
vishal.b62985ca92015-04-17 08:45:51321 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07322 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07323 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27324 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41325 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27326
[email protected]5a60c8b2011-10-19 20:14:29327 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07328 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29329 }
initial.commit586acc5fe2008-07-26 22:42:52330
[email protected]49639fa2011-12-20 23:22:41331 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52332
eroman24bc6a12015-05-06 19:55:48333 EXPECT_TRUE(log.bound().IsCapturing());
[email protected]49639fa2011-12-20 23:22:41334 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15335 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52336
[email protected]ff007e162009-05-23 09:13:15337 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25338
339 // Even in the failure cases that use this function, connections are always
340 // successfully established before the error.
341 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
342 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
343
[email protected]ff007e162009-05-23 09:13:15344 if (out.rv != OK)
345 return out;
346
347 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50348 // Can't use ASSERT_* inside helper functions like this, so
349 // return an error.
[email protected]90499482013-06-01 00:39:50350 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50351 out.rv = ERR_UNEXPECTED;
352 return out;
353 }
[email protected]ff007e162009-05-23 09:13:15354 out.status_line = response->headers->GetStatusLine();
355
[email protected]80a09a82012-11-16 17:40:06356 EXPECT_EQ("127.0.0.1", response->socket_address.host());
357 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19358
[email protected]ff007e162009-05-23 09:13:15359 rv = ReadTransaction(trans.get(), &out.response_data);
360 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40361
mmenke43758e62015-05-04 21:09:46362 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40363 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39364 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40365 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12366 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39367 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40368 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39369 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
370 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15371
[email protected]f3da152d2012-06-02 01:00:57372 std::string line;
373 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
374 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
375
[email protected]79e1fd62013-06-20 06:50:04376 HttpRequestHeaders request_headers;
377 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
378 std::string value;
379 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23380 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04381 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
382 EXPECT_EQ("keep-alive", value);
383
384 std::string response_headers;
385 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23386 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04387 response_headers);
[email protected]3deb9a52010-11-11 00:24:40388
[email protected]b8015c42013-12-24 15:18:19389 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
ttuttle1f2d7e92015-04-28 16:17:47390 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47391 return out;
[email protected]ff007e162009-05-23 09:13:15392 }
initial.commit586acc5fe2008-07-26 22:42:52393
[email protected]5a60c8b2011-10-19 20:14:29394 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
395 size_t reads_count) {
396 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
397 StaticSocketDataProvider* data[] = { &reads };
398 return SimpleGetHelperForData(data, 1);
399 }
400
[email protected]b8015c42013-12-24 15:18:19401 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
402 int64 size = 0;
403 for (size_t i = 0; i < reads_count; ++i)
404 size += data_reads[i].data_len;
405 return size;
406 }
407
[email protected]ff007e162009-05-23 09:13:15408 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
409 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52410
[email protected]ff007e162009-05-23 09:13:15411 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07412
413 void BypassHostCacheOnRefreshHelper(int load_flags);
414
415 void CheckErrorIsPassedBack(int error, IoMode mode);
416
[email protected]4bd46222013-05-14 19:32:23417 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07418 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03419
420 // Original socket limits. Some tests set these. Safest to always restore
421 // them once each test has been run.
422 int old_max_group_sockets_;
423 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15424};
[email protected]231d5a32008-09-13 00:45:27425
bnc57685ae62015-03-10 21:27:20426INSTANTIATE_TEST_CASE_P(NextProto,
427 HttpNetworkTransactionTest,
428 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:43429 kProtoHTTP2_14,
430 kProtoHTTP2));
[email protected]23e482282013-06-14 16:08:02431
[email protected]448d4ca52012-03-04 04:12:23432namespace {
433
[email protected]1826a402014-01-08 15:40:48434class BeforeNetworkStartHandler {
435 public:
436 explicit BeforeNetworkStartHandler(bool defer)
437 : defer_on_before_network_start_(defer),
438 observed_before_network_start_(false) {}
439
440 void OnBeforeNetworkStart(bool* defer) {
441 *defer = defer_on_before_network_start_;
442 observed_before_network_start_ = true;
443 }
444
445 bool observed_before_network_start() const {
446 return observed_before_network_start_;
447 }
448
449 private:
450 const bool defer_on_before_network_start_;
451 bool observed_before_network_start_;
452
453 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
454};
455
[email protected]597a1ab2014-06-26 08:12:27456class BeforeProxyHeadersSentHandler {
457 public:
458 BeforeProxyHeadersSentHandler()
459 : observed_before_proxy_headers_sent_(false) {}
460
[email protected]1252d42f2014-07-01 21:20:20461 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
462 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27463 observed_before_proxy_headers_sent_ = true;
464 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
465 }
466
467 bool observed_before_proxy_headers_sent() const {
468 return observed_before_proxy_headers_sent_;
469 }
470
471 std::string observed_proxy_server_uri() const {
472 return observed_proxy_server_uri_;
473 }
474
475 private:
476 bool observed_before_proxy_headers_sent_;
477 std::string observed_proxy_server_uri_;
478
479 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
480};
481
[email protected]15a5ccf82008-10-23 19:57:43482// Fill |str| with a long header list that consumes >= |size| bytes.
483void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51484 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19485 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
486 const int sizeof_row = strlen(row);
487 const int num_rows = static_cast<int>(
488 ceil(static_cast<float>(size) / sizeof_row));
489 const int sizeof_data = num_rows * sizeof_row;
490 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43491 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51492
[email protected]4ddaf2502008-10-23 18:26:19493 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43494 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19495}
496
[email protected]385a4672009-03-11 22:21:29497// Alternative functions that eliminate randomness and dependency on the local
498// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20499void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29500 static const uint8 bytes[] = {
501 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
502 };
503 static size_t current_byte = 0;
504 for (size_t i = 0; i < n; ++i) {
505 output[i] = bytes[current_byte++];
506 current_byte %= arraysize(bytes);
507 }
508}
509
[email protected]fe2bc6a2009-03-23 16:52:20510void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29511 static const uint8 bytes[] = {
512 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
513 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
514 };
515 static size_t current_byte = 0;
516 for (size_t i = 0; i < n; ++i) {
517 output[i] = bytes[current_byte++];
518 current_byte %= arraysize(bytes);
519 }
520}
521
[email protected]fe2bc6a2009-03-23 16:52:20522std::string MockGetHostName() {
523 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29524}
525
[email protected]e60e47a2010-07-14 03:37:18526template<typename ParentPool>
527class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31528 public:
[email protected]9e1bdd32011-02-03 21:48:34529 CaptureGroupNameSocketPool(HostResolver* host_resolver,
530 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18531
[email protected]d80a4322009-08-14 07:07:49532 const std::string last_group_name_received() const {
533 return last_group_name_;
534 }
535
dmichaeld6e570d2014-12-18 22:30:57536 int RequestSocket(const std::string& group_name,
537 const void* socket_params,
538 RequestPriority priority,
539 ClientSocketHandle* handle,
540 const CompletionCallback& callback,
541 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31542 last_group_name_ = group_name;
543 return ERR_IO_PENDING;
544 }
dmichaeld6e570d2014-12-18 22:30:57545 void CancelRequest(const std::string& group_name,
546 ClientSocketHandle* handle) override {}
547 void ReleaseSocket(const std::string& group_name,
548 scoped_ptr<StreamSocket> socket,
549 int id) override {}
550 void CloseIdleSockets() override {}
551 int IdleSocketCount() const override { return 0; }
552 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31553 return 0;
554 }
dmichaeld6e570d2014-12-18 22:30:57555 LoadState GetLoadState(const std::string& group_name,
556 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31557 return LOAD_STATE_IDLE;
558 }
dmichaeld6e570d2014-12-18 22:30:57559 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26560 return base::TimeDelta();
561 }
[email protected]d80a4322009-08-14 07:07:49562
563 private:
[email protected]04e5be32009-06-26 20:00:31564 std::string last_group_name_;
565};
566
[email protected]ab739042011-04-07 15:22:28567typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
568CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13569typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
570CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06571typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11572CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18573typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
574CaptureGroupNameSSLSocketPool;
575
rkaplowd90695c2015-03-25 22:12:41576template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18577CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34578 HostResolver* host_resolver,
579 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41580 : ParentPool(0, 0, host_resolver, NULL, NULL) {
581}
[email protected]e60e47a2010-07-14 03:37:18582
hashimoto0d3e4fb2015-01-09 05:02:50583template <>
[email protected]2df19bb2010-08-25 20:13:46584CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21585 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34586 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41587 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50588}
[email protected]2df19bb2010-08-25 20:13:46589
[email protected]007b3f82013-04-09 08:46:45590template <>
[email protected]e60e47a2010-07-14 03:37:18591CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21592 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34593 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45594 : SSLClientSocketPool(0,
595 0,
[email protected]007b3f82013-04-09 08:46:45596 cert_verifier,
597 NULL,
598 NULL,
[email protected]284303b62013-11-28 15:11:54599 NULL,
eranm6571b2b2014-12-03 15:53:23600 NULL,
[email protected]007b3f82013-04-09 08:46:45601 std::string(),
602 NULL,
603 NULL,
604 NULL,
605 NULL,
606 NULL,
[email protected]8e458552014-08-05 00:02:15607 NULL) {
608}
[email protected]2227c692010-05-04 15:36:11609
[email protected]231d5a32008-09-13 00:45:27610//-----------------------------------------------------------------------------
611
[email protected]79cb5c12011-09-12 13:12:04612// Helper functions for validating that AuthChallengeInfo's are correctly
613// configured for common cases.
614bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
615 if (!auth_challenge)
616 return false;
617 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23618 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04619 EXPECT_EQ("MyRealm1", auth_challenge->realm);
620 EXPECT_EQ("basic", auth_challenge->scheme);
621 return true;
622}
623
624bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
625 if (!auth_challenge)
626 return false;
627 EXPECT_TRUE(auth_challenge->is_proxy);
628 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
629 EXPECT_EQ("MyRealm1", auth_challenge->realm);
630 EXPECT_EQ("basic", auth_challenge->scheme);
631 return true;
632}
633
634bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
635 if (!auth_challenge)
636 return false;
637 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23638 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04639 EXPECT_EQ("digestive", auth_challenge->realm);
640 EXPECT_EQ("digest", auth_challenge->scheme);
641 return true;
642}
643
644bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
645 if (!auth_challenge)
646 return false;
647 EXPECT_FALSE(auth_challenge->is_proxy);
648 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
649 EXPECT_EQ(std::string(), auth_challenge->realm);
650 EXPECT_EQ("ntlm", auth_challenge->scheme);
651 return true;
652}
653
[email protected]448d4ca52012-03-04 04:12:23654} // namespace
655
[email protected]23e482282013-06-14 16:08:02656TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07657 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40658 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41659 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27660}
661
[email protected]23e482282013-06-14 16:08:02662TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27663 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35664 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
665 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06666 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27667 };
[email protected]31a2bfe2010-02-09 08:03:39668 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
669 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42670 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27671 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
672 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19673 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
674 EXPECT_EQ(reads_size, out.totalReceivedBytes);
ttuttle1f2d7e92015-04-28 16:17:47675 EXPECT_EQ(0u, out.connection_attempts.size());
[email protected]231d5a32008-09-13 00:45:27676}
677
678// Response with no status line.
[email protected]23e482282013-06-14 16:08:02679TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27680 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35681 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06682 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27683 };
[email protected]31a2bfe2010-02-09 08:03:39684 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
685 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42686 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27687 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
688 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19689 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
690 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27691}
692
693// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02694TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27695 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35696 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06697 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27698 };
[email protected]31a2bfe2010-02-09 08:03:39699 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
700 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42701 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27702 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
703 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19704 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
705 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27706}
707
708// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02709TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27710 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35711 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06712 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27713 };
[email protected]31a2bfe2010-02-09 08:03:39714 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
715 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42716 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27717 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
718 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19719 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
720 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27721}
722
723// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02724TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27725 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35726 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06727 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27728 };
[email protected]31a2bfe2010-02-09 08:03:39729 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
730 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42731 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25732 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
733 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19734 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
735 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27736}
737
738// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02739TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27740 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35741 MockRead("\n"),
742 MockRead("\n"),
743 MockRead("Q"),
744 MockRead("J"),
745 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06746 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27747 };
[email protected]31a2bfe2010-02-09 08:03:39748 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
749 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42750 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27751 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
752 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19753 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
754 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27755}
756
757// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02758TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27759 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35760 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06761 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27762 };
[email protected]31a2bfe2010-02-09 08:03:39763 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
764 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42765 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27766 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
767 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19768 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
769 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52770}
771
[email protected]f9d44aa2008-09-23 23:57:17772// Simulate a 204 response, lacking a Content-Length header, sent over a
773// persistent connection. The response should still terminate since a 204
774// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02775TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19776 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17777 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35778 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19779 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06780 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17781 };
[email protected]31a2bfe2010-02-09 08:03:39782 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
783 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42784 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17785 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
786 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19787 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
788 int64 response_size = reads_size - strlen(junk);
789 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17790}
791
[email protected]0877e3d2009-10-17 22:29:57792// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02793TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19794 std::string final_chunk = "0\r\n\r\n";
795 std::string extra_data = "HTTP/1.1 200 OK\r\n";
796 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57797 MockRead data_reads[] = {
798 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
799 MockRead("5\r\nHello\r\n"),
800 MockRead("1\r\n"),
801 MockRead(" \r\n"),
802 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19803 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06804 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57805 };
[email protected]31a2bfe2010-02-09 08:03:39806 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
807 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57808 EXPECT_EQ(OK, out.rv);
809 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
810 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19811 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
812 int64 response_size = reads_size - extra_data.size();
813 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57814}
815
[email protected]9fe44f52010-09-23 18:36:00816// Next tests deal with http://crbug.com/56344.
817
[email protected]23e482282013-06-14 16:08:02818TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00819 MultipleContentLengthHeadersNoTransferEncoding) {
820 MockRead data_reads[] = {
821 MockRead("HTTP/1.1 200 OK\r\n"),
822 MockRead("Content-Length: 10\r\n"),
823 MockRead("Content-Length: 5\r\n\r\n"),
824 };
825 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
826 arraysize(data_reads));
827 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
828}
829
[email protected]23e482282013-06-14 16:08:02830TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04831 DuplicateContentLengthHeadersNoTransferEncoding) {
832 MockRead data_reads[] = {
833 MockRead("HTTP/1.1 200 OK\r\n"),
834 MockRead("Content-Length: 5\r\n"),
835 MockRead("Content-Length: 5\r\n\r\n"),
836 MockRead("Hello"),
837 };
838 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
839 arraysize(data_reads));
840 EXPECT_EQ(OK, out.rv);
841 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
842 EXPECT_EQ("Hello", out.response_data);
843}
844
[email protected]23e482282013-06-14 16:08:02845TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04846 ComplexContentLengthHeadersNoTransferEncoding) {
847 // More than 2 dupes.
848 {
849 MockRead data_reads[] = {
850 MockRead("HTTP/1.1 200 OK\r\n"),
851 MockRead("Content-Length: 5\r\n"),
852 MockRead("Content-Length: 5\r\n"),
853 MockRead("Content-Length: 5\r\n\r\n"),
854 MockRead("Hello"),
855 };
856 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
857 arraysize(data_reads));
858 EXPECT_EQ(OK, out.rv);
859 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
860 EXPECT_EQ("Hello", out.response_data);
861 }
862 // HTTP/1.0
863 {
864 MockRead data_reads[] = {
865 MockRead("HTTP/1.0 200 OK\r\n"),
866 MockRead("Content-Length: 5\r\n"),
867 MockRead("Content-Length: 5\r\n"),
868 MockRead("Content-Length: 5\r\n\r\n"),
869 MockRead("Hello"),
870 };
871 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
872 arraysize(data_reads));
873 EXPECT_EQ(OK, out.rv);
874 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
875 EXPECT_EQ("Hello", out.response_data);
876 }
877 // 2 dupes and one mismatched.
878 {
879 MockRead data_reads[] = {
880 MockRead("HTTP/1.1 200 OK\r\n"),
881 MockRead("Content-Length: 10\r\n"),
882 MockRead("Content-Length: 10\r\n"),
883 MockRead("Content-Length: 5\r\n\r\n"),
884 };
885 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
886 arraysize(data_reads));
887 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
888 }
889}
890
[email protected]23e482282013-06-14 16:08:02891TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00892 MultipleContentLengthHeadersTransferEncoding) {
893 MockRead data_reads[] = {
894 MockRead("HTTP/1.1 200 OK\r\n"),
895 MockRead("Content-Length: 666\r\n"),
896 MockRead("Content-Length: 1337\r\n"),
897 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
898 MockRead("5\r\nHello\r\n"),
899 MockRead("1\r\n"),
900 MockRead(" \r\n"),
901 MockRead("5\r\nworld\r\n"),
902 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06903 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00904 };
905 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
906 arraysize(data_reads));
907 EXPECT_EQ(OK, out.rv);
908 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
909 EXPECT_EQ("Hello world", out.response_data);
910}
911
[email protected]1628fe92011-10-04 23:04:55912// Next tests deal with http://crbug.com/98895.
913
914// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02915TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55916 MockRead data_reads[] = {
917 MockRead("HTTP/1.1 200 OK\r\n"),
918 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
919 MockRead("Content-Length: 5\r\n\r\n"),
920 MockRead("Hello"),
921 };
922 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
923 arraysize(data_reads));
924 EXPECT_EQ(OK, out.rv);
925 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
926 EXPECT_EQ("Hello", out.response_data);
927}
928
[email protected]54a9c6e52012-03-21 20:10:59929// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02930TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59931 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55932 MockRead data_reads[] = {
933 MockRead("HTTP/1.1 200 OK\r\n"),
934 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
935 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
936 MockRead("Content-Length: 5\r\n\r\n"),
937 MockRead("Hello"),
938 };
939 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
940 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59941 EXPECT_EQ(OK, out.rv);
942 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
943 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55944}
945
946// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02947TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55948 MockRead data_reads[] = {
949 MockRead("HTTP/1.1 200 OK\r\n"),
950 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
951 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
952 MockRead("Content-Length: 5\r\n\r\n"),
953 MockRead("Hello"),
954 };
955 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
956 arraysize(data_reads));
957 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
958}
959
[email protected]54a9c6e52012-03-21 20:10:59960// Checks that two identical Location headers result in no error.
961// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02962TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55963 MockRead data_reads[] = {
964 MockRead("HTTP/1.1 302 Redirect\r\n"),
965 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59966 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55967 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06968 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55969 };
970
971 HttpRequestInfo request;
972 request.method = "GET";
973 request.url = GURL("http://redirect.com/");
974 request.load_flags = 0;
975
[email protected]3fe8d2f82013-10-17 08:56:07976 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55977 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41978 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:55979
980 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07981 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55982
[email protected]49639fa2011-12-20 23:22:41983 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55984
[email protected]49639fa2011-12-20 23:22:41985 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55986 EXPECT_EQ(ERR_IO_PENDING, rv);
987
988 EXPECT_EQ(OK, callback.WaitForResult());
989
990 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:50991 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:55992 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
993 std::string url;
994 EXPECT_TRUE(response->headers->IsRedirect(&url));
995 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:15996 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:55997}
998
[email protected]1628fe92011-10-04 23:04:55999// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021000TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551001 MockRead data_reads[] = {
1002 MockRead("HTTP/1.1 302 Redirect\r\n"),
1003 MockRead("Location: http://good.com/\r\n"),
1004 MockRead("Location: http://evil.com/\r\n"),
1005 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061006 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551007 };
1008 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1009 arraysize(data_reads));
1010 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1011}
1012
[email protected]ef0faf2e72009-03-05 23:27:231013// Do a request using the HEAD method. Verify that we don't try to read the
1014// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021015TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421016 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231017 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231018 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231019 request.load_flags = 0;
1020
[email protected]3fe8d2f82013-10-17 08:56:071021 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271022 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411023 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271024 BeforeProxyHeadersSentHandler proxy_headers_handler;
1025 trans->SetBeforeProxyHeadersSentCallback(
1026 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1027 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271028
[email protected]ef0faf2e72009-03-05 23:27:231029 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231030 MockWrite(
1031 "HEAD / HTTP/1.1\r\n"
1032 "Host: www.example.org\r\n"
1033 "Connection: keep-alive\r\n"
1034 "Content-Length: 0\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231035 };
1036 MockRead data_reads1[] = {
1037 MockRead("HTTP/1.1 404 Not Found\r\n"),
1038 MockRead("Server: Blah\r\n"),
1039 MockRead("Content-Length: 1234\r\n\r\n"),
1040
1041 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061042 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231043 };
1044
[email protected]31a2bfe2010-02-09 08:03:391045 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1046 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071047 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231048
[email protected]49639fa2011-12-20 23:22:411049 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231050
[email protected]49639fa2011-12-20 23:22:411051 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421052 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231053
1054 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421055 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231056
[email protected]1c773ea12009-04-28 19:58:421057 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501058 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231059
1060 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501061 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231062 EXPECT_EQ(1234, response->headers->GetContentLength());
1063 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151064 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271065 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231066
1067 std::string server_header;
1068 void* iter = NULL;
1069 bool has_server_header = response->headers->EnumerateHeader(
1070 &iter, "Server", &server_header);
1071 EXPECT_TRUE(has_server_header);
1072 EXPECT_EQ("Blah", server_header);
1073
1074 // Reading should give EOF right away, since there is no message body
1075 // (despite non-zero content-length).
1076 std::string response_data;
1077 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421078 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231079 EXPECT_EQ("", response_data);
1080}
1081
[email protected]23e482282013-06-14 16:08:021082TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071083 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521084
1085 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351086 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1087 MockRead("hello"),
1088 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1089 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061090 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521091 };
[email protected]31a2bfe2010-02-09 08:03:391092 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071093 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521094
[email protected]0b0bf032010-09-21 18:08:501095 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521096 "hello", "world"
1097 };
1098
1099 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421100 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521101 request.method = "GET";
bncce36dca22015-04-21 22:11:231102 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521103 request.load_flags = 0;
1104
[email protected]262eec82013-03-19 21:01:361105 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501106 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271107
[email protected]49639fa2011-12-20 23:22:411108 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521109
[email protected]49639fa2011-12-20 23:22:411110 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421111 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521112
1113 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421114 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521115
[email protected]1c773ea12009-04-28 19:58:421116 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501117 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521118
[email protected]90499482013-06-01 00:39:501119 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251120 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151121 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521122
1123 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571124 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421125 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251126 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521127 }
1128}
1129
[email protected]23e482282013-06-14 16:08:021130TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061131 ScopedVector<UploadElementReader> element_readers;
1132 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071133 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271134
[email protected]1c773ea12009-04-28 19:58:421135 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521136 request.method = "POST";
1137 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271138 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521139 request.load_flags = 0;
1140
[email protected]3fe8d2f82013-10-17 08:56:071141 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271142 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411143 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271144
initial.commit586acc5fe2008-07-26 22:42:521145 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351146 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1147 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1148 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061149 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521150 };
[email protected]31a2bfe2010-02-09 08:03:391151 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071152 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521153
[email protected]49639fa2011-12-20 23:22:411154 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521155
[email protected]49639fa2011-12-20 23:22:411156 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421157 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521158
1159 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421160 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521161
[email protected]1c773ea12009-04-28 19:58:421162 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501163 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521164
[email protected]90499482013-06-01 00:39:501165 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251166 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521167
1168 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571169 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421170 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251171 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521172}
1173
[email protected]3a2d3662009-03-27 03:49:141174// This test is almost the same as Ignores100 above, but the response contains
1175// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571176// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021177TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421178 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141179 request.method = "GET";
1180 request.url = GURL("http://www.foo.com/");
1181 request.load_flags = 0;
1182
[email protected]3fe8d2f82013-10-17 08:56:071183 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271184 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411185 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271186
[email protected]3a2d3662009-03-27 03:49:141187 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571188 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1189 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141190 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061191 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141192 };
[email protected]31a2bfe2010-02-09 08:03:391193 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071194 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141195
[email protected]49639fa2011-12-20 23:22:411196 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141197
[email protected]49639fa2011-12-20 23:22:411198 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421199 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141200
1201 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421202 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141203
[email protected]1c773ea12009-04-28 19:58:421204 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501205 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141206
[email protected]90499482013-06-01 00:39:501207 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141208 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1209
1210 std::string response_data;
1211 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421212 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141213 EXPECT_EQ("hello world", response_data);
1214}
1215
[email protected]23e482282013-06-14 16:08:021216TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
[email protected]ee9410e72010-01-07 01:42:381217 HttpRequestInfo request;
1218 request.method = "POST";
1219 request.url = GURL("http://www.foo.com/");
1220 request.load_flags = 0;
1221
[email protected]3fe8d2f82013-10-17 08:56:071222 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271223 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411224 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271225
[email protected]ee9410e72010-01-07 01:42:381226 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061227 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1228 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381229 };
[email protected]31a2bfe2010-02-09 08:03:391230 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071231 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381232
[email protected]49639fa2011-12-20 23:22:411233 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381234
[email protected]49639fa2011-12-20 23:22:411235 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381236 EXPECT_EQ(ERR_IO_PENDING, rv);
1237
1238 rv = callback.WaitForResult();
1239 EXPECT_EQ(OK, rv);
1240
1241 std::string response_data;
1242 rv = ReadTransaction(trans.get(), &response_data);
1243 EXPECT_EQ(OK, rv);
1244 EXPECT_EQ("", response_data);
1245}
1246
[email protected]23e482282013-06-14 16:08:021247TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381248 HttpRequestInfo request;
1249 request.method = "POST";
1250 request.url = GURL("http://www.foo.com/");
1251 request.load_flags = 0;
1252
[email protected]3fe8d2f82013-10-17 08:56:071253 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271254 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411255 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271256
[email protected]ee9410e72010-01-07 01:42:381257 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061258 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381259 };
[email protected]31a2bfe2010-02-09 08:03:391260 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071261 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381262
[email protected]49639fa2011-12-20 23:22:411263 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381264
[email protected]49639fa2011-12-20 23:22:411265 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381266 EXPECT_EQ(ERR_IO_PENDING, rv);
1267
1268 rv = callback.WaitForResult();
1269 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1270}
1271
[email protected]23e482282013-06-14 16:08:021272void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511273 const MockWrite* write_failure,
1274 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421275 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521276 request.method = "GET";
1277 request.url = GURL("http://www.foo.com/");
1278 request.load_flags = 0;
1279
vishal.b62985ca92015-04-17 08:45:511280 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071281 session_deps_.net_log = &net_log;
1282 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271283
[email protected]202965992011-12-07 23:04:511284 // Written data for successfully sending both requests.
1285 MockWrite data1_writes[] = {
1286 MockWrite("GET / HTTP/1.1\r\n"
1287 "Host: www.foo.com\r\n"
1288 "Connection: keep-alive\r\n\r\n"),
1289 MockWrite("GET / HTTP/1.1\r\n"
1290 "Host: www.foo.com\r\n"
1291 "Connection: keep-alive\r\n\r\n")
1292 };
1293
1294 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521295 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351296 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1297 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061298 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521299 };
[email protected]202965992011-12-07 23:04:511300
1301 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491302 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511303 data1_writes[1] = *write_failure;
1304 } else {
1305 ASSERT_TRUE(read_failure);
1306 data1_reads[2] = *read_failure;
1307 }
1308
1309 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1310 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071311 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521312
1313 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351314 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1315 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061316 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521317 };
[email protected]31a2bfe2010-02-09 08:03:391318 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071319 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521320
thestig9d3bb0c2015-01-24 00:49:511321 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521322 "hello", "world"
1323 };
1324
[email protected]58e32bb2013-01-21 18:23:251325 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521326 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411327 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521328
[email protected]262eec82013-03-19 21:01:361329 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501330 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521331
[email protected]49639fa2011-12-20 23:22:411332 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421333 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521334
1335 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421336 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521337
[email protected]58e32bb2013-01-21 18:23:251338 LoadTimingInfo load_timing_info;
1339 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1340 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1341 if (i == 0) {
1342 first_socket_log_id = load_timing_info.socket_log_id;
1343 } else {
1344 // The second request should be using a new socket.
1345 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1346 }
1347
[email protected]1c773ea12009-04-28 19:58:421348 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501349 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521350
[email protected]90499482013-06-01 00:39:501351 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251352 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521353
1354 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571355 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421356 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251357 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521358 }
1359}
[email protected]3d2a59b2008-09-26 19:44:251360
[email protected]a34f61ee2014-03-18 20:59:491361void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1362 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101363 const MockRead* read_failure,
1364 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491365 HttpRequestInfo request;
1366 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101367 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491368 request.load_flags = 0;
1369
vishal.b62985ca92015-04-17 08:45:511370 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491371 session_deps_.net_log = &net_log;
1372 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1373
[email protected]09356c652014-03-25 15:36:101374 SSLSocketDataProvider ssl1(ASYNC, OK);
1375 SSLSocketDataProvider ssl2(ASYNC, OK);
1376 if (use_spdy) {
1377 ssl1.SetNextProto(GetParam());
1378 ssl2.SetNextProto(GetParam());
1379 }
1380 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1381 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491382
[email protected]09356c652014-03-25 15:36:101383 // SPDY versions of the request and response.
1384 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1385 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1386 scoped_ptr<SpdyFrame> spdy_response(
1387 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1388 scoped_ptr<SpdyFrame> spdy_data(
1389 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491390
[email protected]09356c652014-03-25 15:36:101391 // HTTP/1.1 versions of the request and response.
1392 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1393 "Host: www.foo.com\r\n"
1394 "Connection: keep-alive\r\n\r\n";
1395 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1396 const char kHttpData[] = "hello";
1397
1398 std::vector<MockRead> data1_reads;
1399 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491400 if (write_failure) {
1401 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101402 data1_writes.push_back(*write_failure);
1403 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491404 } else {
1405 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101406 if (use_spdy) {
1407 data1_writes.push_back(CreateMockWrite(*spdy_request));
1408 } else {
1409 data1_writes.push_back(MockWrite(kHttpRequest));
1410 }
1411 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491412 }
1413
[email protected]09356c652014-03-25 15:36:101414 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1415 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491416 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1417
[email protected]09356c652014-03-25 15:36:101418 std::vector<MockRead> data2_reads;
1419 std::vector<MockWrite> data2_writes;
1420
1421 if (use_spdy) {
1422 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1423
1424 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1425 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1426 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1427 } else {
1428 data2_writes.push_back(
1429 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1430
1431 data2_reads.push_back(
1432 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1433 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1434 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1435 }
rch8e6c6c42015-05-01 14:05:131436 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1437 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491438 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1439
1440 // Preconnect a socket.
ttuttle859dc7a2015-04-23 19:42:291441 SSLConfig ssl_config;
[email protected]a34f61ee2014-03-18 20:59:491442 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231443 session->GetNextProtos(&ssl_config.next_protos);
mmenked1205bd2015-07-15 22:26:351444 session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
1445 ssl_config);
[email protected]a34f61ee2014-03-18 20:59:491446 // Wait for the preconnect to complete.
1447 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1448 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101449 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491450
1451 // Make the request.
1452 TestCompletionCallback callback;
1453
1454 scoped_ptr<HttpTransaction> trans(
1455 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1456
1457 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1458 EXPECT_EQ(ERR_IO_PENDING, rv);
1459
1460 rv = callback.WaitForResult();
1461 EXPECT_EQ(OK, rv);
1462
1463 LoadTimingInfo load_timing_info;
1464 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101465 TestLoadTimingNotReused(
1466 load_timing_info,
1467 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491468
1469 const HttpResponseInfo* response = trans->GetResponseInfo();
1470 ASSERT_TRUE(response != NULL);
1471
1472 EXPECT_TRUE(response->headers.get() != NULL);
1473 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1474
1475 std::string response_data;
1476 rv = ReadTransaction(trans.get(), &response_data);
1477 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101478 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491479}
1480
[email protected]23e482282013-06-14 16:08:021481TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231482 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061483 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511484 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1485}
1486
[email protected]23e482282013-06-14 16:08:021487TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061488 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511489 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251490}
1491
[email protected]23e482282013-06-14 16:08:021492TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061493 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511494 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251495}
1496
[email protected]d58ceea82014-06-04 10:55:541497// Make sure that on a 408 response (Request Timeout), the request is retried,
1498// if the socket was a reused keep alive socket.
1499TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1500 MockRead read_failure(SYNCHRONOUS,
1501 "HTTP/1.1 408 Request Timeout\r\n"
1502 "Connection: Keep-Alive\r\n"
1503 "Content-Length: 6\r\n\r\n"
1504 "Pickle");
1505 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1506}
1507
[email protected]a34f61ee2014-03-18 20:59:491508TEST_P(HttpNetworkTransactionTest,
1509 PreconnectErrorNotConnectedOnWrite) {
1510 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101511 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491512}
1513
1514TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1515 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101516 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491517}
1518
1519TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1520 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101521 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1522}
1523
1524TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1525 MockRead read_failure(ASYNC, OK); // EOF
1526 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1527}
1528
[email protected]d58ceea82014-06-04 10:55:541529// Make sure that on a 408 response (Request Timeout), the request is retried,
1530// if the socket was a preconnected (UNUSED_IDLE) socket.
1531TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1532 MockRead read_failure(SYNCHRONOUS,
1533 "HTTP/1.1 408 Request Timeout\r\n"
1534 "Connection: Keep-Alive\r\n"
1535 "Content-Length: 6\r\n\r\n"
1536 "Pickle");
1537 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1538 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1539}
1540
[email protected]09356c652014-03-25 15:36:101541TEST_P(HttpNetworkTransactionTest,
1542 SpdyPreconnectErrorNotConnectedOnWrite) {
1543 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1544 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1545}
1546
1547TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1548 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1549 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1550}
1551
1552TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1553 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1554 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1555}
1556
1557TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1558 MockRead read_failure(ASYNC, OK); // EOF
1559 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491560}
1561
[email protected]23e482282013-06-14 16:08:021562TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421563 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251564 request.method = "GET";
bncce36dca22015-04-21 22:11:231565 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251566 request.load_flags = 0;
1567
[email protected]3fe8d2f82013-10-17 08:56:071568 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271569 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411570 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271571
[email protected]3d2a59b2008-09-26 19:44:251572 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061573 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351574 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1575 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061576 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251577 };
[email protected]31a2bfe2010-02-09 08:03:391578 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071579 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251580
[email protected]49639fa2011-12-20 23:22:411581 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251582
[email protected]49639fa2011-12-20 23:22:411583 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421584 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251585
1586 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421587 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251588}
1589
1590// What do various browsers do when the server closes a non-keepalive
1591// connection without sending any response header or body?
1592//
1593// IE7: error page
1594// Safari 3.1.2 (Windows): error page
1595// Firefox 3.0.1: blank page
1596// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421597// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1598// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021599TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251600 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061601 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351602 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1603 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061604 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251605 };
[email protected]31a2bfe2010-02-09 08:03:391606 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1607 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421608 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251609}
[email protected]038e9a32008-10-08 22:40:161610
[email protected]1826a402014-01-08 15:40:481611// Test that network access can be deferred and resumed.
1612TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1613 HttpRequestInfo request;
1614 request.method = "GET";
bncce36dca22015-04-21 22:11:231615 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481616 request.load_flags = 0;
1617
1618 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1619 scoped_ptr<HttpTransaction> trans(
1620 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1621
1622 // Defer on OnBeforeNetworkStart.
1623 BeforeNetworkStartHandler net_start_handler(true); // defer
1624 trans->SetBeforeNetworkStartCallback(
1625 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1626 base::Unretained(&net_start_handler)));
1627
1628 MockRead data_reads[] = {
1629 MockRead("HTTP/1.0 200 OK\r\n"),
1630 MockRead("Content-Length: 5\r\n\r\n"),
1631 MockRead("hello"),
1632 MockRead(SYNCHRONOUS, 0),
1633 };
1634 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1635 session_deps_.socket_factory->AddSocketDataProvider(&data);
1636
1637 TestCompletionCallback callback;
1638
1639 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1640 EXPECT_EQ(ERR_IO_PENDING, rv);
1641 base::MessageLoop::current()->RunUntilIdle();
1642
1643 // Should have deferred for network start.
1644 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1645 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481646
1647 trans->ResumeNetworkStart();
1648 rv = callback.WaitForResult();
1649 EXPECT_EQ(OK, rv);
1650 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1651
1652 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1653 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1654 if (rv == ERR_IO_PENDING)
1655 rv = callback.WaitForResult();
1656 EXPECT_EQ(5, rv);
1657 trans.reset();
1658}
1659
1660// Test that network use can be deferred and canceled.
1661TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1662 HttpRequestInfo request;
1663 request.method = "GET";
bncce36dca22015-04-21 22:11:231664 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481665 request.load_flags = 0;
1666
1667 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1668 scoped_ptr<HttpTransaction> trans(
1669 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1670
1671 // Defer on OnBeforeNetworkStart.
1672 BeforeNetworkStartHandler net_start_handler(true); // defer
1673 trans->SetBeforeNetworkStartCallback(
1674 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1675 base::Unretained(&net_start_handler)));
1676
1677 TestCompletionCallback callback;
1678
1679 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1680 EXPECT_EQ(ERR_IO_PENDING, rv);
1681 base::MessageLoop::current()->RunUntilIdle();
1682
1683 // Should have deferred for network start.
1684 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1685 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481686}
1687
[email protected]7a5378b2012-11-04 03:25:171688// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1689// tests. There was a bug causing HttpNetworkTransaction to hang in the
1690// destructor in such situations.
1691// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021692TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171693 HttpRequestInfo request;
1694 request.method = "GET";
bncce36dca22015-04-21 22:11:231695 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171696 request.load_flags = 0;
1697
[email protected]bb88e1d32013-05-03 23:11:071698 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361699 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501700 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171701
1702 MockRead data_reads[] = {
1703 MockRead("HTTP/1.0 200 OK\r\n"),
1704 MockRead("Connection: keep-alive\r\n"),
1705 MockRead("Content-Length: 100\r\n\r\n"),
1706 MockRead("hello"),
1707 MockRead(SYNCHRONOUS, 0),
1708 };
1709 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071710 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171711
1712 TestCompletionCallback callback;
1713
1714 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1715 EXPECT_EQ(ERR_IO_PENDING, rv);
1716
1717 rv = callback.WaitForResult();
1718 EXPECT_EQ(OK, rv);
1719
1720 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501721 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171722 if (rv == ERR_IO_PENDING)
1723 rv = callback.WaitForResult();
1724 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501725 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171726 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1727
1728 trans.reset();
[email protected]2da659e2013-05-23 20:51:341729 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171730 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1731}
1732
[email protected]23e482282013-06-14 16:08:021733TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171734 HttpRequestInfo request;
1735 request.method = "GET";
bncce36dca22015-04-21 22:11:231736 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171737 request.load_flags = 0;
1738
[email protected]bb88e1d32013-05-03 23:11:071739 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361740 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501741 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171742
1743 MockRead data_reads[] = {
1744 MockRead("HTTP/1.0 200 OK\r\n"),
1745 MockRead("Connection: keep-alive\r\n"),
1746 MockRead("Content-Length: 100\r\n\r\n"),
1747 MockRead(SYNCHRONOUS, 0),
1748 };
1749 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071750 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171751
1752 TestCompletionCallback callback;
1753
1754 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1755 EXPECT_EQ(ERR_IO_PENDING, rv);
1756
1757 rv = callback.WaitForResult();
1758 EXPECT_EQ(OK, rv);
1759
1760 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501761 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171762 if (rv == ERR_IO_PENDING)
1763 rv = callback.WaitForResult();
1764 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1765
1766 trans.reset();
[email protected]2da659e2013-05-23 20:51:341767 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171768 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1769}
1770
[email protected]0b0bf032010-09-21 18:08:501771// Test that we correctly reuse a keep-alive connection after not explicitly
1772// reading the body.
[email protected]23e482282013-06-14 16:08:021773TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131774 HttpRequestInfo request;
1775 request.method = "GET";
1776 request.url = GURL("http://www.foo.com/");
1777 request.load_flags = 0;
1778
vishal.b62985ca92015-04-17 08:45:511779 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071780 session_deps_.net_log = &net_log;
1781 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271782
[email protected]0b0bf032010-09-21 18:08:501783 // Note that because all these reads happen in the same
1784 // StaticSocketDataProvider, it shows that the same socket is being reused for
1785 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131786 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501787 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1788 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131789 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501790 MockRead("HTTP/1.1 302 Found\r\n"
1791 "Content-Length: 0\r\n\r\n"),
1792 MockRead("HTTP/1.1 302 Found\r\n"
1793 "Content-Length: 5\r\n\r\n"
1794 "hello"),
1795 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1796 "Content-Length: 0\r\n\r\n"),
1797 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1798 "Content-Length: 5\r\n\r\n"
1799 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131800 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1801 MockRead("hello"),
1802 };
1803 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071804 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131805
1806 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061807 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131808 };
1809 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071810 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131811
[email protected]0b0bf032010-09-21 18:08:501812 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1813 std::string response_lines[kNumUnreadBodies];
1814
[email protected]58e32bb2013-01-21 18:23:251815 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501816 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411817 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131818
[email protected]262eec82013-03-19 21:01:361819 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501820 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131821
[email protected]49639fa2011-12-20 23:22:411822 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131823 EXPECT_EQ(ERR_IO_PENDING, rv);
1824
1825 rv = callback.WaitForResult();
1826 EXPECT_EQ(OK, rv);
1827
[email protected]58e32bb2013-01-21 18:23:251828 LoadTimingInfo load_timing_info;
1829 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1830 if (i == 0) {
1831 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1832 first_socket_log_id = load_timing_info.socket_log_id;
1833 } else {
1834 TestLoadTimingReused(load_timing_info);
1835 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1836 }
1837
[email protected]fc31d6a42010-06-24 18:05:131838 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501839 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131840
[email protected]90499482013-06-01 00:39:501841 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501842 response_lines[i] = response->headers->GetStatusLine();
1843
1844 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131845 }
[email protected]0b0bf032010-09-21 18:08:501846
1847 const char* const kStatusLines[] = {
1848 "HTTP/1.1 204 No Content",
1849 "HTTP/1.1 205 Reset Content",
1850 "HTTP/1.1 304 Not Modified",
1851 "HTTP/1.1 302 Found",
1852 "HTTP/1.1 302 Found",
1853 "HTTP/1.1 301 Moved Permanently",
1854 "HTTP/1.1 301 Moved Permanently",
1855 };
1856
mostynb91e0da982015-01-20 19:17:271857 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1858 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501859
1860 for (int i = 0; i < kNumUnreadBodies; ++i)
1861 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1862
[email protected]49639fa2011-12-20 23:22:411863 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361864 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501865 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411866 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501867 EXPECT_EQ(ERR_IO_PENDING, rv);
1868 rv = callback.WaitForResult();
1869 EXPECT_EQ(OK, rv);
1870 const HttpResponseInfo* response = trans->GetResponseInfo();
1871 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501872 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501873 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1874 std::string response_data;
1875 rv = ReadTransaction(trans.get(), &response_data);
1876 EXPECT_EQ(OK, rv);
1877 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131878}
1879
[email protected]038e9a32008-10-08 22:40:161880// Test the request-challenge-retry sequence for basic auth.
1881// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021882TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421883 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161884 request.method = "GET";
bncce36dca22015-04-21 22:11:231885 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161886 request.load_flags = 0;
1887
vishal.b62985ca92015-04-17 08:45:511888 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071889 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071890 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271891 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411892 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271893
[email protected]f9ee6b52008-11-08 06:46:231894 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231895 MockWrite(
1896 "GET / HTTP/1.1\r\n"
1897 "Host: www.example.org\r\n"
1898 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231899 };
1900
[email protected]038e9a32008-10-08 22:40:161901 MockRead data_reads1[] = {
1902 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1903 // Give a couple authenticate options (only the middle one is actually
1904 // supported).
[email protected]22927ad2009-09-21 19:56:191905 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161906 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1907 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1908 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1909 // Large content-length -- won't matter, as connection will be reset.
1910 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061911 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161912 };
1913
1914 // After calling trans->RestartWithAuth(), this is the request we should
1915 // be issuing -- the final header line contains the credentials.
1916 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231917 MockWrite(
1918 "GET / HTTP/1.1\r\n"
1919 "Host: www.example.org\r\n"
1920 "Connection: keep-alive\r\n"
1921 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161922 };
1923
1924 // Lastly, the server responds with the actual content.
1925 MockRead data_reads2[] = {
1926 MockRead("HTTP/1.0 200 OK\r\n"),
1927 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1928 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061929 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161930 };
1931
[email protected]31a2bfe2010-02-09 08:03:391932 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1933 data_writes1, arraysize(data_writes1));
1934 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1935 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071936 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1937 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161938
[email protected]49639fa2011-12-20 23:22:411939 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161940
[email protected]49639fa2011-12-20 23:22:411941 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421942 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161943
1944 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421945 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161946
[email protected]58e32bb2013-01-21 18:23:251947 LoadTimingInfo load_timing_info1;
1948 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1949 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1950
[email protected]b8015c42013-12-24 15:18:191951 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1952 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1953
[email protected]1c773ea12009-04-28 19:58:421954 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501955 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041956 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161957
[email protected]49639fa2011-12-20 23:22:411958 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161959
[email protected]49639fa2011-12-20 23:22:411960 rv = trans->RestartWithAuth(
1961 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421962 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161963
1964 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421965 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161966
[email protected]58e32bb2013-01-21 18:23:251967 LoadTimingInfo load_timing_info2;
1968 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1969 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1970 // The load timing after restart should have a new socket ID, and times after
1971 // those of the first load timing.
1972 EXPECT_LE(load_timing_info1.receive_headers_end,
1973 load_timing_info2.connect_timing.connect_start);
1974 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1975
[email protected]b8015c42013-12-24 15:18:191976 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1977 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1978
[email protected]038e9a32008-10-08 22:40:161979 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501980 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161981 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1982 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161983}
1984
[email protected]23e482282013-06-14 16:08:021985TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461986 HttpRequestInfo request;
1987 request.method = "GET";
bncce36dca22015-04-21 22:11:231988 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:291989 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:461990
[email protected]3fe8d2f82013-10-17 08:56:071991 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271992 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411993 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271994
[email protected]861fcd52009-08-26 02:33:461995 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:231996 MockWrite(
1997 "GET / HTTP/1.1\r\n"
1998 "Host: www.example.org\r\n"
1999 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462000 };
2001
2002 MockRead data_reads[] = {
2003 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2004 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2005 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2006 // Large content-length -- won't matter, as connection will be reset.
2007 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062008 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462009 };
2010
[email protected]31a2bfe2010-02-09 08:03:392011 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2012 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072013 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412014 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462015
[email protected]49639fa2011-12-20 23:22:412016 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462017 EXPECT_EQ(ERR_IO_PENDING, rv);
2018
2019 rv = callback.WaitForResult();
2020 EXPECT_EQ(0, rv);
2021
[email protected]b8015c42013-12-24 15:18:192022 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2023 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2024
[email protected]861fcd52009-08-26 02:33:462025 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502026 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462027 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2028}
2029
[email protected]2d2697f92009-02-18 21:00:322030// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2031// connection.
[email protected]23e482282013-06-14 16:08:022032TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422033 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322034 request.method = "GET";
bncce36dca22015-04-21 22:11:232035 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322036 request.load_flags = 0;
2037
vishal.b62985ca92015-04-17 08:45:512038 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072039 session_deps_.net_log = &log;
2040 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272041
[email protected]2d2697f92009-02-18 21:00:322042 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232043 MockWrite(
2044 "GET / HTTP/1.1\r\n"
2045 "Host: www.example.org\r\n"
2046 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322047
bncce36dca22015-04-21 22:11:232048 // After calling trans->RestartWithAuth(), this is the request we should
2049 // be issuing -- the final header line contains the credentials.
2050 MockWrite(
2051 "GET / HTTP/1.1\r\n"
2052 "Host: www.example.org\r\n"
2053 "Connection: keep-alive\r\n"
2054 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322055 };
2056
2057 MockRead data_reads1[] = {
2058 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2059 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2060 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2061 MockRead("Content-Length: 14\r\n\r\n"),
2062 MockRead("Unauthorized\r\n"),
2063
2064 // Lastly, the server responds with the actual content.
2065 MockRead("HTTP/1.1 200 OK\r\n"),
2066 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502067 MockRead("Content-Length: 5\r\n\r\n"),
2068 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322069 };
2070
[email protected]2d0a4f92011-05-05 16:38:462071 // If there is a regression where we disconnect a Keep-Alive
2072 // connection during an auth roundtrip, we'll end up reading this.
2073 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062074 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462075 };
2076
[email protected]31a2bfe2010-02-09 08:03:392077 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2078 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462079 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2080 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072081 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2082 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322083
[email protected]49639fa2011-12-20 23:22:412084 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322085
[email protected]262eec82013-03-19 21:01:362086 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502087 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412088 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422089 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322090
2091 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422092 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322093
[email protected]58e32bb2013-01-21 18:23:252094 LoadTimingInfo load_timing_info1;
2095 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2096 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2097
[email protected]1c773ea12009-04-28 19:58:422098 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502099 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042100 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322101
[email protected]49639fa2011-12-20 23:22:412102 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322103
[email protected]49639fa2011-12-20 23:22:412104 rv = trans->RestartWithAuth(
2105 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422106 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322107
2108 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422109 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322110
[email protected]58e32bb2013-01-21 18:23:252111 LoadTimingInfo load_timing_info2;
2112 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2113 TestLoadTimingReused(load_timing_info2);
2114 // The load timing after restart should have the same socket ID, and times
2115 // those of the first load timing.
2116 EXPECT_LE(load_timing_info1.receive_headers_end,
2117 load_timing_info2.send_start);
2118 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2119
[email protected]2d2697f92009-02-18 21:00:322120 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502121 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322122 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502123 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192124
2125 std::string response_data;
2126 rv = ReadTransaction(trans.get(), &response_data);
2127 EXPECT_EQ(OK, rv);
2128 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2129 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322130}
2131
2132// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2133// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022134TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422135 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322136 request.method = "GET";
bncce36dca22015-04-21 22:11:232137 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322138 request.load_flags = 0;
2139
[email protected]bb88e1d32013-05-03 23:11:072140 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272141
[email protected]2d2697f92009-02-18 21:00:322142 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232143 MockWrite(
2144 "GET / HTTP/1.1\r\n"
2145 "Host: www.example.org\r\n"
2146 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322147
bncce36dca22015-04-21 22:11:232148 // After calling trans->RestartWithAuth(), this is the request we should
2149 // be issuing -- the final header line contains the credentials.
2150 MockWrite(
2151 "GET / HTTP/1.1\r\n"
2152 "Host: www.example.org\r\n"
2153 "Connection: keep-alive\r\n"
2154 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322155 };
2156
[email protected]2d2697f92009-02-18 21:00:322157 MockRead data_reads1[] = {
2158 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2159 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312160 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322161
2162 // Lastly, the server responds with the actual content.
2163 MockRead("HTTP/1.1 200 OK\r\n"),
2164 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502165 MockRead("Content-Length: 5\r\n\r\n"),
2166 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322167 };
2168
[email protected]2d0a4f92011-05-05 16:38:462169 // An incorrect reconnect would cause this to be read.
2170 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062171 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462172 };
2173
[email protected]31a2bfe2010-02-09 08:03:392174 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2175 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462176 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2177 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072178 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2179 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322180
[email protected]49639fa2011-12-20 23:22:412181 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322182
[email protected]262eec82013-03-19 21:01:362183 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502184 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412185 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422186 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322187
2188 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422189 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322190
[email protected]1c773ea12009-04-28 19:58:422191 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502192 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042193 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322194
[email protected]49639fa2011-12-20 23:22:412195 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322196
[email protected]49639fa2011-12-20 23:22:412197 rv = trans->RestartWithAuth(
2198 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422199 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322200
2201 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422202 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322203
2204 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502205 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322206 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502207 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322208}
2209
2210// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2211// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022212TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422213 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322214 request.method = "GET";
bncce36dca22015-04-21 22:11:232215 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322216 request.load_flags = 0;
2217
[email protected]bb88e1d32013-05-03 23:11:072218 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272219
[email protected]2d2697f92009-02-18 21:00:322220 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232221 MockWrite(
2222 "GET / HTTP/1.1\r\n"
2223 "Host: www.example.org\r\n"
2224 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322225
bncce36dca22015-04-21 22:11:232226 // After calling trans->RestartWithAuth(), this is the request we should
2227 // be issuing -- the final header line contains the credentials.
2228 MockWrite(
2229 "GET / HTTP/1.1\r\n"
2230 "Host: www.example.org\r\n"
2231 "Connection: keep-alive\r\n"
2232 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322233 };
2234
2235 // Respond with 5 kb of response body.
2236 std::string large_body_string("Unauthorized");
2237 large_body_string.append(5 * 1024, ' ');
2238 large_body_string.append("\r\n");
2239
2240 MockRead data_reads1[] = {
2241 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2242 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2243 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2244 // 5134 = 12 + 5 * 1024 + 2
2245 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062246 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322247
2248 // Lastly, the server responds with the actual content.
2249 MockRead("HTTP/1.1 200 OK\r\n"),
2250 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502251 MockRead("Content-Length: 5\r\n\r\n"),
2252 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322253 };
2254
[email protected]2d0a4f92011-05-05 16:38:462255 // An incorrect reconnect would cause this to be read.
2256 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062257 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462258 };
2259
[email protected]31a2bfe2010-02-09 08:03:392260 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2261 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462262 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2263 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072264 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2265 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322266
[email protected]49639fa2011-12-20 23:22:412267 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322268
[email protected]262eec82013-03-19 21:01:362269 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502270 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412271 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422272 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322273
2274 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422275 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322276
[email protected]1c773ea12009-04-28 19:58:422277 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502278 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042279 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322280
[email protected]49639fa2011-12-20 23:22:412281 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322282
[email protected]49639fa2011-12-20 23:22:412283 rv = trans->RestartWithAuth(
2284 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422285 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322286
2287 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422288 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322289
2290 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502291 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322292 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502293 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322294}
2295
2296// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312297// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022298TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312299 HttpRequestInfo request;
2300 request.method = "GET";
bncce36dca22015-04-21 22:11:232301 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312302 request.load_flags = 0;
2303
[email protected]bb88e1d32013-05-03 23:11:072304 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272305
[email protected]11203f012009-11-12 23:02:312306 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232307 MockWrite(
2308 "GET / HTTP/1.1\r\n"
2309 "Host: www.example.org\r\n"
2310 "Connection: keep-alive\r\n\r\n"),
2311 // This simulates the seemingly successful write to a closed connection
2312 // if the bug is not fixed.
2313 MockWrite(
2314 "GET / HTTP/1.1\r\n"
2315 "Host: www.example.org\r\n"
2316 "Connection: keep-alive\r\n"
2317 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312318 };
2319
2320 MockRead data_reads1[] = {
2321 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2322 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2323 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2324 MockRead("Content-Length: 14\r\n\r\n"),
2325 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062326 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312327 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062328 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312329 };
2330
2331 // After calling trans->RestartWithAuth(), this is the request we should
2332 // be issuing -- the final header line contains the credentials.
2333 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232334 MockWrite(
2335 "GET / HTTP/1.1\r\n"
2336 "Host: www.example.org\r\n"
2337 "Connection: keep-alive\r\n"
2338 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312339 };
2340
2341 // Lastly, the server responds with the actual content.
2342 MockRead data_reads2[] = {
2343 MockRead("HTTP/1.1 200 OK\r\n"),
2344 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502345 MockRead("Content-Length: 5\r\n\r\n"),
2346 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312347 };
2348
[email protected]31a2bfe2010-02-09 08:03:392349 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2350 data_writes1, arraysize(data_writes1));
2351 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2352 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072353 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2354 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312355
[email protected]49639fa2011-12-20 23:22:412356 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312357
[email protected]262eec82013-03-19 21:01:362358 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502359 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412360 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312361 EXPECT_EQ(ERR_IO_PENDING, rv);
2362
2363 rv = callback1.WaitForResult();
2364 EXPECT_EQ(OK, rv);
2365
2366 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502367 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042368 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312369
[email protected]49639fa2011-12-20 23:22:412370 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312371
[email protected]49639fa2011-12-20 23:22:412372 rv = trans->RestartWithAuth(
2373 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312374 EXPECT_EQ(ERR_IO_PENDING, rv);
2375
2376 rv = callback2.WaitForResult();
2377 EXPECT_EQ(OK, rv);
2378
2379 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502380 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312381 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502382 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312383}
2384
[email protected]394816e92010-08-03 07:38:592385// Test the request-challenge-retry sequence for basic auth, over a connection
2386// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012387TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2388 HttpRequestInfo request;
2389 request.method = "GET";
bncce36dca22015-04-21 22:11:232390 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012391 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292392 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012393
2394 // Configure against proxy server "myproxy:70".
2395 session_deps_.proxy_service.reset(
2396 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512397 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012398 session_deps_.net_log = log.bound().net_log();
2399 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2400
2401 // Since we have proxy, should try to establish tunnel.
2402 MockWrite data_writes1[] = {
2403 MockWrite(
bncce36dca22015-04-21 22:11:232404 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2405 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012406 "Proxy-Connection: keep-alive\r\n\r\n"),
2407
2408 // After calling trans->RestartWithAuth(), this is the request we should
2409 // be issuing -- the final header line contains the credentials.
2410 MockWrite(
bncce36dca22015-04-21 22:11:232411 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2412 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012413 "Proxy-Connection: keep-alive\r\n"
2414 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2415
2416 MockWrite(
2417 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:232418 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012419 "Connection: keep-alive\r\n\r\n"),
2420 };
2421
2422 // The proxy responds to the connect with a 407, using a persistent
2423 // connection.
2424 MockRead data_reads1[] = {
2425 // No credentials.
2426 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2427 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
2428
2429 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2430
2431 MockRead("HTTP/1.1 200 OK\r\n"),
2432 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2433 MockRead("Content-Length: 5\r\n\r\n"),
2434 MockRead(SYNCHRONOUS, "hello"),
2435 };
2436
2437 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2438 data_writes1, arraysize(data_writes1));
2439 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2440 SSLSocketDataProvider ssl(ASYNC, OK);
2441 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2442
2443 TestCompletionCallback callback1;
2444
2445 scoped_ptr<HttpTransaction> trans(
2446 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2447
2448 int rv = trans->Start(&request, callback1.callback(), log.bound());
2449 EXPECT_EQ(ERR_IO_PENDING, rv);
2450
2451 rv = callback1.WaitForResult();
2452 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462453 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012454 log.GetEntries(&entries);
2455 size_t pos = ExpectLogContainsSomewhere(
2456 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2457 NetLog::PHASE_NONE);
2458 ExpectLogContainsSomewhere(
2459 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2460 NetLog::PHASE_NONE);
2461
2462 const HttpResponseInfo* response = trans->GetResponseInfo();
2463 ASSERT_TRUE(response != NULL);
2464 EXPECT_FALSE(response->headers->IsKeepAlive());
2465 ASSERT_FALSE(response->headers.get() == NULL);
2466 EXPECT_EQ(407, response->headers->response_code());
2467 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2468 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2469
2470 LoadTimingInfo load_timing_info;
2471 // CONNECT requests and responses are handled at the connect job level, so
2472 // the transaction does not yet have a connection.
2473 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2474
2475 TestCompletionCallback callback2;
2476
2477 rv =
2478 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2479 EXPECT_EQ(ERR_IO_PENDING, rv);
2480
2481 rv = callback2.WaitForResult();
2482 EXPECT_EQ(OK, rv);
2483
2484 response = trans->GetResponseInfo();
2485 ASSERT_TRUE(response != NULL);
2486
2487 EXPECT_TRUE(response->headers->IsKeepAlive());
2488 EXPECT_EQ(200, response->headers->response_code());
2489 EXPECT_EQ(5, response->headers->GetContentLength());
2490 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2491
2492 // The password prompt info should not be set.
2493 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2494
2495 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2496 TestLoadTimingNotReusedWithPac(load_timing_info,
2497 CONNECT_TIMING_HAS_SSL_TIMES);
2498
2499 trans.reset();
2500 session->CloseAllConnections();
2501}
2502
2503// Test the request-challenge-retry sequence for basic auth, over a connection
2504// that requires a restart when setting up an SSL tunnel.
2505TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592506 HttpRequestInfo request;
2507 request.method = "GET";
bncce36dca22015-04-21 22:11:232508 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592509 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292510 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592511
[email protected]cb9bf6ca2011-01-28 13:15:272512 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072513 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202514 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512515 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072516 session_deps_.net_log = log.bound().net_log();
2517 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272518
[email protected]394816e92010-08-03 07:38:592519 // Since we have proxy, should try to establish tunnel.
2520 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232521 MockWrite(
2522 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2523 "Host: www.example.org\r\n"
2524 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592525
bncce36dca22015-04-21 22:11:232526 // After calling trans->RestartWithAuth(), this is the request we should
2527 // be issuing -- the final header line contains the credentials.
2528 MockWrite(
2529 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2530 "Host: www.example.org\r\n"
2531 "Proxy-Connection: keep-alive\r\n"
2532 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592533
bncce36dca22015-04-21 22:11:232534 MockWrite(
2535 "GET / HTTP/1.1\r\n"
2536 "Host: www.example.org\r\n"
2537 "Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592538 };
2539
2540 // The proxy responds to the connect with a 407, using a persistent
2541 // connection.
2542 MockRead data_reads1[] = {
2543 // No credentials.
2544 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2545 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2546 MockRead("Proxy-Connection: close\r\n\r\n"),
2547
2548 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2549
2550 MockRead("HTTP/1.1 200 OK\r\n"),
2551 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502552 MockRead("Content-Length: 5\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062553 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592554 };
2555
2556 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2557 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072558 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:062559 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072560 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592561
[email protected]49639fa2011-12-20 23:22:412562 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592563
[email protected]262eec82013-03-19 21:01:362564 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502565 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502566
[email protected]49639fa2011-12-20 23:22:412567 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592568 EXPECT_EQ(ERR_IO_PENDING, rv);
2569
2570 rv = callback1.WaitForResult();
2571 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462572 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402573 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592574 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402575 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592576 NetLog::PHASE_NONE);
2577 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402578 entries, pos,
[email protected]394816e92010-08-03 07:38:592579 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2580 NetLog::PHASE_NONE);
2581
2582 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502583 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012584 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502585 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592586 EXPECT_EQ(407, response->headers->response_code());
2587 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042588 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592589
[email protected]029c83b62013-01-24 05:28:202590 LoadTimingInfo load_timing_info;
2591 // CONNECT requests and responses are handled at the connect job level, so
2592 // the transaction does not yet have a connection.
2593 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2594
[email protected]49639fa2011-12-20 23:22:412595 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592596
[email protected]49639fa2011-12-20 23:22:412597 rv = trans->RestartWithAuth(
2598 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592599 EXPECT_EQ(ERR_IO_PENDING, rv);
2600
2601 rv = callback2.WaitForResult();
2602 EXPECT_EQ(OK, rv);
2603
2604 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502605 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592606
2607 EXPECT_TRUE(response->headers->IsKeepAlive());
2608 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502609 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592610 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2611
2612 // The password prompt info should not be set.
2613 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502614
[email protected]029c83b62013-01-24 05:28:202615 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2616 TestLoadTimingNotReusedWithPac(load_timing_info,
2617 CONNECT_TIMING_HAS_SSL_TIMES);
2618
[email protected]0b0bf032010-09-21 18:08:502619 trans.reset();
[email protected]102e27c2011-02-23 01:01:312620 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592621}
2622
[email protected]11203f012009-11-12 23:02:312623// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012624// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2625TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2626 HttpRequestInfo request;
2627 request.method = "GET";
bncce36dca22015-04-21 22:11:232628 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012629 // Ensure that proxy authentication is attempted even
2630 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292631 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012632
2633 // Configure against proxy server "myproxy:70".
2634 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512635 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012636 session_deps_.net_log = log.bound().net_log();
2637 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2638
2639 scoped_ptr<HttpTransaction> trans(
2640 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2641
2642 // Since we have proxy, should try to establish tunnel.
2643 MockWrite data_writes1[] = {
2644 MockWrite(
bncce36dca22015-04-21 22:11:232645 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2646 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012647 "Proxy-Connection: keep-alive\r\n\r\n"),
2648
2649 // After calling trans->RestartWithAuth(), this is the request we should
2650 // be issuing -- the final header line contains the credentials.
2651 MockWrite(
bncce36dca22015-04-21 22:11:232652 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2653 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012654 "Proxy-Connection: keep-alive\r\n"
2655 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2656 };
2657
2658 // The proxy responds to the connect with a 407, using a persistent
2659 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2660 MockRead data_reads1[] = {
2661 // No credentials.
2662 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2663 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2664 MockRead("Proxy-Connection: keep-alive\r\n"),
2665 MockRead("Content-Length: 10\r\n\r\n"),
2666 MockRead("0123456789"),
2667
2668 // Wrong credentials (wrong password).
2669 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2670 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2671 MockRead("Proxy-Connection: keep-alive\r\n"),
2672 MockRead("Content-Length: 10\r\n\r\n"),
2673 // No response body because the test stops reading here.
2674 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2675 };
2676
2677 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2678 data_writes1, arraysize(data_writes1));
2679 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2680
2681 TestCompletionCallback callback1;
2682
2683 int rv = trans->Start(&request, callback1.callback(), log.bound());
2684 EXPECT_EQ(ERR_IO_PENDING, rv);
2685
2686 rv = callback1.WaitForResult();
2687 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462688 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012689 log.GetEntries(&entries);
2690 size_t pos = ExpectLogContainsSomewhere(
2691 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2692 NetLog::PHASE_NONE);
2693 ExpectLogContainsSomewhere(
2694 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2695 NetLog::PHASE_NONE);
2696
2697 const HttpResponseInfo* response = trans->GetResponseInfo();
2698 ASSERT_TRUE(response);
2699 ASSERT_TRUE(response->headers);
2700 EXPECT_TRUE(response->headers->IsKeepAlive());
2701 EXPECT_EQ(407, response->headers->response_code());
2702 EXPECT_EQ(10, response->headers->GetContentLength());
2703 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2704 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2705
2706 TestCompletionCallback callback2;
2707
2708 // Wrong password (should be "bar").
2709 rv =
2710 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2711 EXPECT_EQ(ERR_IO_PENDING, rv);
2712
2713 rv = callback2.WaitForResult();
2714 EXPECT_EQ(OK, rv);
2715
2716 response = trans->GetResponseInfo();
2717 ASSERT_TRUE(response);
2718 ASSERT_TRUE(response->headers);
2719 EXPECT_TRUE(response->headers->IsKeepAlive());
2720 EXPECT_EQ(407, response->headers->response_code());
2721 EXPECT_EQ(10, response->headers->GetContentLength());
2722 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2723 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2724
2725 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2726 // out of scope.
2727 session->CloseAllConnections();
2728}
2729
2730// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2731// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2732TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272733 HttpRequestInfo request;
2734 request.method = "GET";
bncce36dca22015-04-21 22:11:232735 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272736 // Ensure that proxy authentication is attempted even
2737 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292738 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272739
[email protected]2d2697f92009-02-18 21:00:322740 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072741 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512742 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072743 session_deps_.net_log = log.bound().net_log();
2744 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322745
[email protected]262eec82013-03-19 21:01:362746 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502747 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322748
[email protected]2d2697f92009-02-18 21:00:322749 // Since we have proxy, should try to establish tunnel.
2750 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232751 MockWrite(
2752 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2753 "Host: www.example.org\r\n"
2754 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322755
bncce36dca22015-04-21 22:11:232756 // After calling trans->RestartWithAuth(), this is the request we should
2757 // be issuing -- the final header line contains the credentials.
2758 MockWrite(
2759 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2760 "Host: www.example.org\r\n"
2761 "Proxy-Connection: keep-alive\r\n"
2762 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322763 };
2764
2765 // The proxy responds to the connect with a 407, using a persistent
2766 // connection.
2767 MockRead data_reads1[] = {
2768 // No credentials.
2769 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2770 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2771 MockRead("Content-Length: 10\r\n\r\n"),
2772 MockRead("0123456789"),
2773
2774 // Wrong credentials (wrong password).
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 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062779 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322780 };
2781
[email protected]31a2bfe2010-02-09 08:03:392782 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2783 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072784 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322785
[email protected]49639fa2011-12-20 23:22:412786 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322787
[email protected]49639fa2011-12-20 23:22:412788 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422789 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322790
2791 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422792 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462793 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402794 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392795 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402796 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392797 NetLog::PHASE_NONE);
2798 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402799 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392800 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2801 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322802
[email protected]1c773ea12009-04-28 19:58:422803 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242804 ASSERT_TRUE(response);
2805 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322806 EXPECT_TRUE(response->headers->IsKeepAlive());
2807 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012808 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422809 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042810 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322811
[email protected]49639fa2011-12-20 23:22:412812 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322813
2814 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412815 rv = trans->RestartWithAuth(
2816 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422817 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322818
2819 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422820 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322821
2822 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242823 ASSERT_TRUE(response);
2824 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322825 EXPECT_TRUE(response->headers->IsKeepAlive());
2826 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012827 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422828 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042829 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132830
[email protected]e60e47a2010-07-14 03:37:182831 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2832 // out of scope.
[email protected]102e27c2011-02-23 01:01:312833 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322834}
2835
[email protected]a8e9b162009-03-12 00:06:442836// Test that we don't read the response body when we fail to establish a tunnel,
2837// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022838TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272839 HttpRequestInfo request;
2840 request.method = "GET";
bncce36dca22015-04-21 22:11:232841 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272842 request.load_flags = 0;
2843
[email protected]a8e9b162009-03-12 00:06:442844 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072845 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442846
[email protected]bb88e1d32013-05-03 23:11:072847 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442848
[email protected]262eec82013-03-19 21:01:362849 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502850 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442851
[email protected]a8e9b162009-03-12 00:06:442852 // Since we have proxy, should try to establish tunnel.
2853 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232854 MockWrite(
2855 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2856 "Host: www.example.org\r\n"
2857 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442858 };
2859
2860 // The proxy responds to the connect with a 407.
2861 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:242862 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2863 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2864 MockRead("Content-Length: 10\r\n\r\n"),
2865 MockRead("0123456789"), // Should not be reached.
2866 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:442867 };
2868
[email protected]31a2bfe2010-02-09 08:03:392869 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2870 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072871 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442872
[email protected]49639fa2011-12-20 23:22:412873 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442874
[email protected]49639fa2011-12-20 23:22:412875 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422876 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442877
2878 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422879 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442880
[email protected]1c773ea12009-04-28 19:58:422881 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242882 ASSERT_TRUE(response);
2883 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:442884 EXPECT_TRUE(response->headers->IsKeepAlive());
2885 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:422886 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442887
2888 std::string response_data;
2889 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422890 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182891
2892 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:312893 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:442894}
2895
ttuttle7933c112015-01-06 00:55:242896// Test that we don't pass extraneous headers from the proxy's response to the
2897// caller when the proxy responds to CONNECT with 407.
2898TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
2899 HttpRequestInfo request;
2900 request.method = "GET";
bncce36dca22015-04-21 22:11:232901 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:242902 request.load_flags = 0;
2903
2904 // Configure against proxy server "myproxy:70".
2905 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2906
2907 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2908
2909 scoped_ptr<HttpTransaction> trans(
2910 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2911
2912 // Since we have proxy, should try to establish tunnel.
2913 MockWrite data_writes[] = {
2914 MockWrite(
bncce36dca22015-04-21 22:11:232915 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2916 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:242917 "Proxy-Connection: keep-alive\r\n\r\n"),
2918 };
2919
2920 // The proxy responds to the connect with a 407.
2921 MockRead data_reads[] = {
2922 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2923 MockRead("X-Foo: bar\r\n"),
2924 MockRead("Set-Cookie: foo=bar\r\n"),
2925 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2926 MockRead("Content-Length: 10\r\n\r\n"),
2927 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2928 };
2929
2930 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
2931 arraysize(data_writes));
2932 session_deps_.socket_factory->AddSocketDataProvider(&data);
2933
2934 TestCompletionCallback callback;
2935
2936 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2937 EXPECT_EQ(ERR_IO_PENDING, rv);
2938
2939 rv = callback.WaitForResult();
2940 EXPECT_EQ(OK, rv);
2941
2942 const HttpResponseInfo* response = trans->GetResponseInfo();
2943 ASSERT_TRUE(response);
2944 ASSERT_TRUE(response->headers);
2945 EXPECT_TRUE(response->headers->IsKeepAlive());
2946 EXPECT_EQ(407, response->headers->response_code());
2947 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2948 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
2949 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
2950
2951 std::string response_data;
2952 rv = ReadTransaction(trans.get(), &response_data);
2953 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
2954
2955 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
2956 session->CloseAllConnections();
2957}
2958
[email protected]8fdbcd22010-05-05 02:54:522959// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
2960// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:022961TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:522962 HttpRequestInfo request;
2963 request.method = "GET";
bncce36dca22015-04-21 22:11:232964 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:522965 request.load_flags = 0;
2966
[email protected]cb9bf6ca2011-01-28 13:15:272967 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:072968 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272969 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412970 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272971
[email protected]8fdbcd22010-05-05 02:54:522972 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232973 MockWrite(
2974 "GET / HTTP/1.1\r\n"
2975 "Host: www.example.org\r\n"
2976 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:522977 };
2978
2979 MockRead data_reads1[] = {
2980 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
2981 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2982 // Large content-length -- won't matter, as connection will be reset.
2983 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062984 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:522985 };
2986
2987 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2988 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072989 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:522990
[email protected]49639fa2011-12-20 23:22:412991 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:522992
[email protected]49639fa2011-12-20 23:22:412993 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:522994 EXPECT_EQ(ERR_IO_PENDING, rv);
2995
2996 rv = callback.WaitForResult();
2997 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
2998}
2999
[email protected]7a67a8152010-11-05 18:31:103000// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3001// through a non-authenticating proxy. The request should fail with
3002// ERR_UNEXPECTED_PROXY_AUTH.
3003// Note that it is impossible to detect if an HTTP server returns a 407 through
3004// a non-authenticating proxy - there is nothing to indicate whether the
3005// response came from the proxy or the server, so it is treated as if the proxy
3006// issued the challenge.
[email protected]23e482282013-06-14 16:08:023007TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233008 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273009 HttpRequestInfo request;
3010 request.method = "GET";
bncce36dca22015-04-21 22:11:233011 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273012
[email protected]bb88e1d32013-05-03 23:11:073013 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513014 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073015 session_deps_.net_log = log.bound().net_log();
3016 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103017
[email protected]7a67a8152010-11-05 18:31:103018 // Since we have proxy, should try to establish tunnel.
3019 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233020 MockWrite(
3021 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3022 "Host: www.example.org\r\n"
3023 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103024
bncce36dca22015-04-21 22:11:233025 MockWrite(
3026 "GET / HTTP/1.1\r\n"
3027 "Host: www.example.org\r\n"
3028 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103029 };
3030
3031 MockRead data_reads1[] = {
3032 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3033
3034 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3035 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3036 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063037 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103038 };
3039
3040 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3041 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073042 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063043 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073044 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103045
[email protected]49639fa2011-12-20 23:22:413046 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103047
[email protected]262eec82013-03-19 21:01:363048 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503049 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103050
[email protected]49639fa2011-12-20 23:22:413051 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103052 EXPECT_EQ(ERR_IO_PENDING, rv);
3053
3054 rv = callback1.WaitForResult();
3055 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463056 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403057 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103058 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403059 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103060 NetLog::PHASE_NONE);
3061 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403062 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103063 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3064 NetLog::PHASE_NONE);
3065}
[email protected]2df19bb2010-08-25 20:13:463066
[email protected]029c83b62013-01-24 05:28:203067// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023068TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203069 HttpRequestInfo request1;
3070 request1.method = "GET";
bncce36dca22015-04-21 22:11:233071 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203072
3073 HttpRequestInfo request2;
3074 request2.method = "GET";
bncce36dca22015-04-21 22:11:233075 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203076
3077 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073078 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203079 ProxyService::CreateFixed("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513080 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073081 session_deps_.net_log = log.bound().net_log();
3082 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203083
3084 // Since we have proxy, should try to establish tunnel.
3085 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233086 MockWrite(
3087 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3088 "Host: www.example.org\r\n"
3089 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203090
bncce36dca22015-04-21 22:11:233091 MockWrite(
3092 "GET /1 HTTP/1.1\r\n"
3093 "Host: www.example.org\r\n"
3094 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203095
bncce36dca22015-04-21 22:11:233096 MockWrite(
3097 "GET /2 HTTP/1.1\r\n"
3098 "Host: www.example.org\r\n"
3099 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203100 };
3101
3102 // The proxy responds to the connect with a 407, using a persistent
3103 // connection.
3104 MockRead data_reads1[] = {
3105 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3106
3107 MockRead("HTTP/1.1 200 OK\r\n"),
3108 MockRead("Content-Length: 1\r\n\r\n"),
3109 MockRead(SYNCHRONOUS, "1"),
3110
3111 MockRead("HTTP/1.1 200 OK\r\n"),
3112 MockRead("Content-Length: 2\r\n\r\n"),
3113 MockRead(SYNCHRONOUS, "22"),
3114 };
3115
3116 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3117 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073118 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203119 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073120 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203121
3122 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363123 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503124 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203125
3126 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3127 EXPECT_EQ(ERR_IO_PENDING, rv);
3128
3129 rv = callback1.WaitForResult();
3130 EXPECT_EQ(OK, rv);
3131
3132 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3133 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503134 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203135 EXPECT_EQ(1, response1->headers->GetContentLength());
3136
3137 LoadTimingInfo load_timing_info1;
3138 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3139 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3140
3141 trans1.reset();
3142
3143 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363144 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503145 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203146
3147 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3148 EXPECT_EQ(ERR_IO_PENDING, rv);
3149
3150 rv = callback2.WaitForResult();
3151 EXPECT_EQ(OK, rv);
3152
3153 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3154 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503155 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203156 EXPECT_EQ(2, response2->headers->GetContentLength());
3157
3158 LoadTimingInfo load_timing_info2;
3159 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3160 TestLoadTimingReused(load_timing_info2);
3161
3162 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3163
3164 trans2.reset();
3165 session->CloseAllConnections();
3166}
3167
3168// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023169TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203170 HttpRequestInfo request1;
3171 request1.method = "GET";
bncce36dca22015-04-21 22:11:233172 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203173
3174 HttpRequestInfo request2;
3175 request2.method = "GET";
bncce36dca22015-04-21 22:11:233176 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203177
3178 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073179 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203180 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513181 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073182 session_deps_.net_log = log.bound().net_log();
3183 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203184
3185 // Since we have proxy, should try to establish tunnel.
3186 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233187 MockWrite(
3188 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3189 "Host: www.example.org\r\n"
3190 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203191
bncce36dca22015-04-21 22:11:233192 MockWrite(
3193 "GET /1 HTTP/1.1\r\n"
3194 "Host: www.example.org\r\n"
3195 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203196
bncce36dca22015-04-21 22:11:233197 MockWrite(
3198 "GET /2 HTTP/1.1\r\n"
3199 "Host: www.example.org\r\n"
3200 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203201 };
3202
3203 // The proxy responds to the connect with a 407, using a persistent
3204 // connection.
3205 MockRead data_reads1[] = {
3206 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3207
3208 MockRead("HTTP/1.1 200 OK\r\n"),
3209 MockRead("Content-Length: 1\r\n\r\n"),
3210 MockRead(SYNCHRONOUS, "1"),
3211
3212 MockRead("HTTP/1.1 200 OK\r\n"),
3213 MockRead("Content-Length: 2\r\n\r\n"),
3214 MockRead(SYNCHRONOUS, "22"),
3215 };
3216
3217 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3218 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073219 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203220 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073221 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203222
3223 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363224 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503225 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203226
3227 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3228 EXPECT_EQ(ERR_IO_PENDING, rv);
3229
3230 rv = callback1.WaitForResult();
3231 EXPECT_EQ(OK, rv);
3232
3233 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3234 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503235 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203236 EXPECT_EQ(1, response1->headers->GetContentLength());
3237
3238 LoadTimingInfo load_timing_info1;
3239 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3240 TestLoadTimingNotReusedWithPac(load_timing_info1,
3241 CONNECT_TIMING_HAS_SSL_TIMES);
3242
3243 trans1.reset();
3244
3245 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363246 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203248
3249 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3250 EXPECT_EQ(ERR_IO_PENDING, rv);
3251
3252 rv = callback2.WaitForResult();
3253 EXPECT_EQ(OK, rv);
3254
3255 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3256 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503257 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203258 EXPECT_EQ(2, response2->headers->GetContentLength());
3259
3260 LoadTimingInfo load_timing_info2;
3261 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3262 TestLoadTimingReusedWithPac(load_timing_info2);
3263
3264 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3265
3266 trans2.reset();
3267 session->CloseAllConnections();
3268}
3269
[email protected]2df19bb2010-08-25 20:13:463270// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023271TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273272 HttpRequestInfo request;
3273 request.method = "GET";
bncce36dca22015-04-21 22:11:233274 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273275
[email protected]2df19bb2010-08-25 20:13:463276 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073277 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113278 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513279 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073280 session_deps_.net_log = log.bound().net_log();
3281 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463282
[email protected]2df19bb2010-08-25 20:13:463283 // Since we have proxy, should use full url
3284 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233285 MockWrite(
3286 "GET http://www.example.org/ HTTP/1.1\r\n"
3287 "Host: www.example.org\r\n"
3288 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463289 };
3290
3291 MockRead data_reads1[] = {
3292 MockRead("HTTP/1.1 200 OK\r\n"),
3293 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3294 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063295 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463296 };
3297
3298 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3299 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073300 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063301 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073302 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463303
[email protected]49639fa2011-12-20 23:22:413304 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463305
[email protected]262eec82013-03-19 21:01:363306 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503307 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503308
[email protected]49639fa2011-12-20 23:22:413309 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463310 EXPECT_EQ(ERR_IO_PENDING, rv);
3311
3312 rv = callback1.WaitForResult();
3313 EXPECT_EQ(OK, rv);
3314
[email protected]58e32bb2013-01-21 18:23:253315 LoadTimingInfo load_timing_info;
3316 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3317 TestLoadTimingNotReused(load_timing_info,
3318 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3319
[email protected]2df19bb2010-08-25 20:13:463320 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503321 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463322
3323 EXPECT_TRUE(response->headers->IsKeepAlive());
3324 EXPECT_EQ(200, response->headers->response_code());
3325 EXPECT_EQ(100, response->headers->GetContentLength());
3326 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3327
3328 // The password prompt info should not be set.
3329 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3330}
3331
[email protected]7642b5ae2010-09-01 20:55:173332// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023333TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273334 HttpRequestInfo request;
3335 request.method = "GET";
bncce36dca22015-04-21 22:11:233336 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273337 request.load_flags = 0;
3338
[email protected]7642b5ae2010-09-01 20:55:173339 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073340 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113341 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513342 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073343 session_deps_.net_log = log.bound().net_log();
3344 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173345
bncce36dca22015-04-21 22:11:233346 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463347 scoped_ptr<SpdyFrame> req(
3348 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133349 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:173350
[email protected]23e482282013-06-14 16:08:023351 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3352 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173353 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133354 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:173355 };
3356
rch8e6c6c42015-05-01 14:05:133357 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3358 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073359 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173360
[email protected]8ddf8322012-02-23 18:08:063361 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023362 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073363 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173364
[email protected]49639fa2011-12-20 23:22:413365 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173366
[email protected]262eec82013-03-19 21:01:363367 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503368 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503369
[email protected]49639fa2011-12-20 23:22:413370 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173371 EXPECT_EQ(ERR_IO_PENDING, rv);
3372
3373 rv = callback1.WaitForResult();
3374 EXPECT_EQ(OK, rv);
3375
[email protected]58e32bb2013-01-21 18:23:253376 LoadTimingInfo load_timing_info;
3377 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3378 TestLoadTimingNotReused(load_timing_info,
3379 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3380
[email protected]7642b5ae2010-09-01 20:55:173381 const HttpResponseInfo* response = trans->GetResponseInfo();
3382 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503383 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173384 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3385
3386 std::string response_data;
3387 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233388 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173389}
3390
[email protected]1c173852014-06-19 12:51:503391// Verifies that a session which races and wins against the owning transaction
3392// (completing prior to host resolution), doesn't fail the transaction.
3393// Regression test for crbug.com/334413.
3394TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3395 HttpRequestInfo request;
3396 request.method = "GET";
bncce36dca22015-04-21 22:11:233397 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:503398 request.load_flags = 0;
3399
3400 // Configure SPDY proxy server "proxy:70".
3401 session_deps_.proxy_service.reset(
3402 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513403 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:503404 session_deps_.net_log = log.bound().net_log();
3405 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3406
bncce36dca22015-04-21 22:11:233407 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:503408 scoped_ptr<SpdyFrame> req(
3409 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133410 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:503411
3412 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3413 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3414 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133415 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:503416 };
3417
rch8e6c6c42015-05-01 14:05:133418 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3419 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:503420 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3421
3422 SSLSocketDataProvider ssl(ASYNC, OK);
3423 ssl.SetNextProto(GetParam());
3424 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3425
3426 TestCompletionCallback callback1;
3427
3428 scoped_ptr<HttpTransaction> trans(
3429 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3430
3431 // Stall the hostname resolution begun by the transaction.
3432 session_deps_.host_resolver->set_synchronous_mode(false);
3433 session_deps_.host_resolver->set_ondemand_mode(true);
3434
3435 int rv = trans->Start(&request, callback1.callback(), log.bound());
3436 EXPECT_EQ(ERR_IO_PENDING, rv);
3437
3438 // Race a session to the proxy, which completes first.
3439 session_deps_.host_resolver->set_ondemand_mode(false);
3440 SpdySessionKey key(
3441 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3442 base::WeakPtr<SpdySession> spdy_session =
3443 CreateSecureSpdySession(session, key, log.bound());
3444
3445 // Unstall the resolution begun by the transaction.
3446 session_deps_.host_resolver->set_ondemand_mode(true);
3447 session_deps_.host_resolver->ResolveAllPending();
3448
3449 EXPECT_FALSE(callback1.have_result());
3450 rv = callback1.WaitForResult();
3451 EXPECT_EQ(OK, rv);
3452
3453 const HttpResponseInfo* response = trans->GetResponseInfo();
3454 ASSERT_TRUE(response != NULL);
3455 ASSERT_TRUE(response->headers.get() != NULL);
3456 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3457
3458 std::string response_data;
3459 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3460 EXPECT_EQ(kUploadData, response_data);
3461}
3462
[email protected]dc7bd1c52010-11-12 00:01:133463// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023464TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273465 HttpRequestInfo request;
3466 request.method = "GET";
bncce36dca22015-04-21 22:11:233467 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273468 request.load_flags = 0;
3469
[email protected]79cb5c12011-09-12 13:12:043470 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073471 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043472 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513473 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073474 session_deps_.net_log = log.bound().net_log();
3475 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133476
[email protected]dc7bd1c52010-11-12 00:01:133477 // The first request will be a bare GET, the second request will be a
3478 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193479 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463480 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133481 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463482 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133483 };
[email protected]ff98d7f02012-03-22 21:44:193484 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463485 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3486 arraysize(kExtraAuthorizationHeaders) / 2,
3487 false,
3488 3,
3489 LOWEST,
3490 false));
[email protected]dc7bd1c52010-11-12 00:01:133491 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133492 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:133493 };
3494
3495 // The first response is a 407 proxy authentication challenge, and the second
3496 // response will be a 200 response since the second request includes a valid
3497 // Authorization header.
3498 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463499 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133500 };
[email protected]ff98d7f02012-03-22 21:44:193501 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023502 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133503 "407 Proxy Authentication Required",
3504 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3505 1));
[email protected]ff98d7f02012-03-22 21:44:193506 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023507 spdy_util_.ConstructSpdyBodyFrame(1, true));
3508 scoped_ptr<SpdyFrame> resp_data(
3509 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3510 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133511 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133512 CreateMockRead(*resp_authentication, 1),
3513 CreateMockRead(*body_authentication, 2),
3514 CreateMockRead(*resp_data, 4),
3515 CreateMockRead(*body_data, 5),
3516 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:133517 };
3518
rch8e6c6c42015-05-01 14:05:133519 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3520 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073521 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133522
[email protected]8ddf8322012-02-23 18:08:063523 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023524 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073525 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133526
[email protected]49639fa2011-12-20 23:22:413527 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133528
[email protected]262eec82013-03-19 21:01:363529 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503530 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133531
[email protected]49639fa2011-12-20 23:22:413532 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133533 EXPECT_EQ(ERR_IO_PENDING, rv);
3534
3535 rv = callback1.WaitForResult();
3536 EXPECT_EQ(OK, rv);
3537
3538 const HttpResponseInfo* const response = trans->GetResponseInfo();
3539
3540 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503541 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133542 EXPECT_EQ(407, response->headers->response_code());
3543 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043544 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133545
[email protected]49639fa2011-12-20 23:22:413546 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133547
[email protected]49639fa2011-12-20 23:22:413548 rv = trans->RestartWithAuth(
3549 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133550 EXPECT_EQ(ERR_IO_PENDING, rv);
3551
3552 rv = callback2.WaitForResult();
3553 EXPECT_EQ(OK, rv);
3554
3555 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3556
3557 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503558 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133559 EXPECT_EQ(200, response_restart->headers->response_code());
3560 // The password prompt info should not be set.
3561 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3562}
3563
[email protected]d9da5fe2010-10-13 22:37:163564// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023565TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273566 HttpRequestInfo request;
3567 request.method = "GET";
bncce36dca22015-04-21 22:11:233568 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273569 request.load_flags = 0;
3570
[email protected]d9da5fe2010-10-13 22:37:163571 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073572 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113573 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513574 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073575 session_deps_.net_log = log.bound().net_log();
3576 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163577
[email protected]262eec82013-03-19 21:01:363578 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503579 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163580
bncce36dca22015-04-21 22:11:233581 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343582 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233583 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3584 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:163585
bncce36dca22015-04-21 22:11:233586 const char get[] =
3587 "GET / HTTP/1.1\r\n"
3588 "Host: www.example.org\r\n"
3589 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193590 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023591 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3592 scoped_ptr<SpdyFrame> conn_resp(
3593 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163594 const char resp[] = "HTTP/1.1 200 OK\r\n"
3595 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193596 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023597 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193598 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023599 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193600 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203601 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043602
3603 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133604 CreateMockWrite(*connect, 0),
3605 CreateMockWrite(*wrapped_get, 2),
3606 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:043607 };
3608
[email protected]d9da5fe2010-10-13 22:37:163609 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133610 CreateMockRead(*conn_resp, 1, ASYNC),
3611 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
3612 CreateMockRead(*wrapped_body, 4, ASYNC),
3613 CreateMockRead(*wrapped_body, 5, ASYNC),
3614 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:163615 };
3616
rch8e6c6c42015-05-01 14:05:133617 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3618 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073619 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163620
[email protected]8ddf8322012-02-23 18:08:063621 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023622 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063624 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073625 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163626
[email protected]49639fa2011-12-20 23:22:413627 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163628
[email protected]49639fa2011-12-20 23:22:413629 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163630 EXPECT_EQ(ERR_IO_PENDING, rv);
3631
3632 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:133633 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:163634
[email protected]58e32bb2013-01-21 18:23:253635 LoadTimingInfo load_timing_info;
3636 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3637 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3638
[email protected]d9da5fe2010-10-13 22:37:163639 const HttpResponseInfo* response = trans->GetResponseInfo();
3640 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503641 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163642 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3643
3644 std::string response_data;
3645 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3646 EXPECT_EQ("1234567890", response_data);
3647}
3648
3649// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023650TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273651 HttpRequestInfo request;
3652 request.method = "GET";
bncce36dca22015-04-21 22:11:233653 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273654 request.load_flags = 0;
3655
[email protected]d9da5fe2010-10-13 22:37:163656 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073657 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113658 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513659 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073660 session_deps_.net_log = log.bound().net_log();
3661 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163662
[email protected]262eec82013-03-19 21:01:363663 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503664 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163665
bncce36dca22015-04-21 22:11:233666 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343667 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233668 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3669 // fetch https://www.example.org/ via SPDY
3670 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:463671 scoped_ptr<SpdyFrame> get(
3672 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023673 scoped_ptr<SpdyFrame> wrapped_get(
3674 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3675 scoped_ptr<SpdyFrame> conn_resp(
3676 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3677 scoped_ptr<SpdyFrame> get_resp(
3678 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193679 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023680 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3681 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3682 scoped_ptr<SpdyFrame> wrapped_body(
3683 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193684 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203685 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193686 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203687 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043688
3689 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:093690 CreateMockWrite(*connect, 0),
3691 CreateMockWrite(*wrapped_get, 2),
3692 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:043693 CreateMockWrite(*window_update_body, 7),
3694 };
3695
[email protected]d9da5fe2010-10-13 22:37:163696 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:093697 CreateMockRead(*conn_resp, 1, ASYNC),
3698 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:133699 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:093700 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:133701 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163702 };
3703
rch32320842015-05-16 15:57:093704 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3705 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073706 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163707
[email protected]8ddf8322012-02-23 18:08:063708 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023709 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073710 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063711 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023712 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073713 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163714
[email protected]49639fa2011-12-20 23:22:413715 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163716
[email protected]49639fa2011-12-20 23:22:413717 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163718 EXPECT_EQ(ERR_IO_PENDING, rv);
3719
rch32320842015-05-16 15:57:093720 // Allow the SpdyProxyClientSocket's write callback to complete.
3721 base::MessageLoop::current()->RunUntilIdle();
3722 // Now allow the read of the response to complete.
3723 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:163724 rv = callback1.WaitForResult();
3725 EXPECT_EQ(OK, rv);
3726
[email protected]58e32bb2013-01-21 18:23:253727 LoadTimingInfo load_timing_info;
3728 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3729 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3730
[email protected]d9da5fe2010-10-13 22:37:163731 const HttpResponseInfo* response = trans->GetResponseInfo();
3732 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503733 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163734 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3735
3736 std::string response_data;
3737 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233738 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163739}
3740
3741// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023742TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273743 HttpRequestInfo request;
3744 request.method = "GET";
bncce36dca22015-04-21 22:11:233745 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273746 request.load_flags = 0;
3747
[email protected]d9da5fe2010-10-13 22:37:163748 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073749 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113750 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513751 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073752 session_deps_.net_log = log.bound().net_log();
3753 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163754
[email protected]262eec82013-03-19 21:01:363755 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503756 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163757
bncce36dca22015-04-21 22:11:233758 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343759 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233760 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:203761 scoped_ptr<SpdyFrame> get(
3762 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163763
3764 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133765 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:163766 };
3767
[email protected]23e482282013-06-14 16:08:023768 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3769 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163770 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133771 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:163772 };
3773
rch8e6c6c42015-05-01 14:05:133774 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3775 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073776 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163777
[email protected]8ddf8322012-02-23 18:08:063778 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023779 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073780 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063781 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023782 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073783 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163784
[email protected]49639fa2011-12-20 23:22:413785 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163786
[email protected]49639fa2011-12-20 23:22:413787 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163788 EXPECT_EQ(ERR_IO_PENDING, rv);
3789
3790 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173791 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163792
[email protected]4eddbc732012-08-09 05:40:173793 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163794}
3795
[email protected]f6c63db52013-02-02 00:35:223796// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3797// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023798TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223799 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3800 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073801 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223802 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513803 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073804 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223805 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:503806 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223807
3808 HttpRequestInfo request1;
3809 request1.method = "GET";
bncce36dca22015-04-21 22:11:233810 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223811 request1.load_flags = 0;
3812
3813 HttpRequestInfo request2;
3814 request2.method = "GET";
bncce36dca22015-04-21 22:11:233815 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:223816 request2.load_flags = 0;
3817
bncce36dca22015-04-21 22:11:233818 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343819 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233820 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023821 scoped_ptr<SpdyFrame> conn_resp1(
3822 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223823
bncce36dca22015-04-21 22:11:233824 // Fetch https://www.example.org/ via HTTP.
3825 const char get1[] =
3826 "GET / HTTP/1.1\r\n"
3827 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223828 "Connection: keep-alive\r\n\r\n";
3829 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023830 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223831 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3832 "Content-Length: 1\r\n\r\n";
3833 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023834 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3835 scoped_ptr<SpdyFrame> wrapped_body1(
3836 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223837 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203838 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223839
bncce36dca22015-04-21 22:11:233840 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293841 SpdyHeaderBlock connect2_block;
3842 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bncce36dca22015-04-21 22:11:233843 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
3844 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
[email protected]745aa9c2014-06-27 02:21:293845 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223846 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293847 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393848
[email protected]23e482282013-06-14 16:08:023849 scoped_ptr<SpdyFrame> conn_resp2(
3850 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223851
bncce36dca22015-04-21 22:11:233852 // Fetch https://mail.example.org/ via HTTP.
3853 const char get2[] =
3854 "GET / HTTP/1.1\r\n"
3855 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223856 "Connection: keep-alive\r\n\r\n";
3857 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023858 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223859 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3860 "Content-Length: 2\r\n\r\n";
3861 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023862 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223863 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023864 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223865
3866 MockWrite spdy_writes[] = {
3867 CreateMockWrite(*connect1, 0),
3868 CreateMockWrite(*wrapped_get1, 2),
3869 CreateMockWrite(*connect2, 5),
3870 CreateMockWrite(*wrapped_get2, 7),
3871 };
3872
3873 MockRead spdy_reads[] = {
3874 CreateMockRead(*conn_resp1, 1, ASYNC),
3875 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3876 CreateMockRead(*wrapped_body1, 4, ASYNC),
3877 CreateMockRead(*conn_resp2, 6, ASYNC),
3878 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3879 CreateMockRead(*wrapped_body2, 9, ASYNC),
3880 MockRead(ASYNC, 0, 10),
3881 };
3882
mmenke11eb5152015-06-09 14:50:503883 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3884 arraysize(spdy_writes));
3885 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223886
3887 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023888 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:503889 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:223890 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:503891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:223892 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:503893 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:223894
3895 TestCompletionCallback callback;
3896
[email protected]262eec82013-03-19 21:01:363897 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503898 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223899 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:503900 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223901
3902 LoadTimingInfo load_timing_info;
3903 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3904 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3905
3906 const HttpResponseInfo* response = trans->GetResponseInfo();
3907 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503908 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:223909 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3910
3911 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:293912 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:503913 rv = trans->Read(buf.get(), 256, callback.callback());
3914 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223915
[email protected]262eec82013-03-19 21:01:363916 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503917 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:223918 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:503919 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223920
3921 LoadTimingInfo load_timing_info2;
3922 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3923 // Even though the SPDY connection is reused, a new tunnelled connection has
3924 // to be created, so the socket's load timing looks like a fresh connection.
3925 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
3926
3927 // The requests should have different IDs, since they each are using their own
3928 // separate stream.
3929 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
3930
mmenke11eb5152015-06-09 14:50:503931 rv = trans2->Read(buf.get(), 256, callback.callback());
3932 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:223933}
3934
3935// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3936// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:023937TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223938 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
3939 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073940 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223941 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513942 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073943 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223944 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:503945 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223946
3947 HttpRequestInfo request1;
3948 request1.method = "GET";
bncce36dca22015-04-21 22:11:233949 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223950 request1.load_flags = 0;
3951
3952 HttpRequestInfo request2;
3953 request2.method = "GET";
bncce36dca22015-04-21 22:11:233954 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:223955 request2.load_flags = 0;
3956
bncce36dca22015-04-21 22:11:233957 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343958 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233959 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023960 scoped_ptr<SpdyFrame> conn_resp1(
3961 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223962
bncce36dca22015-04-21 22:11:233963 // Fetch https://www.example.org/ via HTTP.
3964 const char get1[] =
3965 "GET / HTTP/1.1\r\n"
3966 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223967 "Connection: keep-alive\r\n\r\n";
3968 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023969 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223970 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3971 "Content-Length: 1\r\n\r\n";
3972 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023973 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3974 scoped_ptr<SpdyFrame> wrapped_body1(
3975 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223976 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203977 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223978
bncce36dca22015-04-21 22:11:233979 // Fetch https://www.example.org/2 via HTTP.
3980 const char get2[] =
3981 "GET /2 HTTP/1.1\r\n"
3982 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223983 "Connection: keep-alive\r\n\r\n";
3984 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023985 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223986 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3987 "Content-Length: 2\r\n\r\n";
3988 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023989 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223990 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023991 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223992
3993 MockWrite spdy_writes[] = {
3994 CreateMockWrite(*connect1, 0),
3995 CreateMockWrite(*wrapped_get1, 2),
3996 CreateMockWrite(*wrapped_get2, 5),
3997 };
3998
3999 MockRead spdy_reads[] = {
4000 CreateMockRead(*conn_resp1, 1, ASYNC),
4001 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4002 CreateMockRead(*wrapped_body1, 4, ASYNC),
4003 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4004 CreateMockRead(*wrapped_body2, 7, ASYNC),
4005 MockRead(ASYNC, 0, 8),
4006 };
4007
mmenke11eb5152015-06-09 14:50:504008 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4009 arraysize(spdy_writes));
4010 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224011
4012 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024013 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504014 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224015 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504016 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224017
4018 TestCompletionCallback callback;
4019
[email protected]262eec82013-03-19 21:01:364020 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504021 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224022 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4023 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224024
4025 rv = callback.WaitForResult();
4026 EXPECT_EQ(OK, rv);
4027
4028 LoadTimingInfo load_timing_info;
4029 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4030 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4031
4032 const HttpResponseInfo* response = trans->GetResponseInfo();
4033 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504034 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224035 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4036
4037 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294038 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504039 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224040 trans.reset();
4041
[email protected]262eec82013-03-19 21:01:364042 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504043 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224044 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4045 EXPECT_EQ(ERR_IO_PENDING, rv);
4046
[email protected]f6c63db52013-02-02 00:35:224047 rv = callback.WaitForResult();
4048 EXPECT_EQ(OK, rv);
4049
4050 LoadTimingInfo load_timing_info2;
4051 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4052 TestLoadTimingReused(load_timing_info2);
4053
4054 // The requests should have the same ID.
4055 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4056
[email protected]90499482013-06-01 00:39:504057 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224058}
4059
4060// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4061// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504062TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224063 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074064 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224065 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514066 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074067 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224068 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504069 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224070
4071 HttpRequestInfo request1;
4072 request1.method = "GET";
bncce36dca22015-04-21 22:11:234073 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224074 request1.load_flags = 0;
4075
4076 HttpRequestInfo request2;
4077 request2.method = "GET";
bncce36dca22015-04-21 22:11:234078 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224079 request2.load_flags = 0;
4080
bncce36dca22015-04-21 22:11:234081 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024082 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234083 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294084 scoped_ptr<SpdyFrame> get1(
4085 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024086 scoped_ptr<SpdyFrame> get_resp1(
4087 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4088 scoped_ptr<SpdyFrame> body1(
4089 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224090
bncce36dca22015-04-21 22:11:234091 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024092 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234093 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294094 scoped_ptr<SpdyFrame> get2(
4095 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024096 scoped_ptr<SpdyFrame> get_resp2(
4097 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4098 scoped_ptr<SpdyFrame> body2(
4099 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224100
4101 MockWrite spdy_writes[] = {
4102 CreateMockWrite(*get1, 0),
4103 CreateMockWrite(*get2, 3),
4104 };
4105
4106 MockRead spdy_reads[] = {
4107 CreateMockRead(*get_resp1, 1, ASYNC),
4108 CreateMockRead(*body1, 2, ASYNC),
4109 CreateMockRead(*get_resp2, 4, ASYNC),
4110 CreateMockRead(*body2, 5, ASYNC),
4111 MockRead(ASYNC, 0, 6),
4112 };
4113
mmenke11eb5152015-06-09 14:50:504114 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4115 arraysize(spdy_writes));
4116 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224117
4118 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024119 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504120 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224121
4122 TestCompletionCallback callback;
4123
[email protected]262eec82013-03-19 21:01:364124 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504125 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224126 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504127 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224128
4129 LoadTimingInfo load_timing_info;
4130 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4131 TestLoadTimingNotReused(load_timing_info,
4132 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4133
4134 const HttpResponseInfo* response = trans->GetResponseInfo();
4135 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504136 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224137 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4138
4139 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294140 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504141 rv = trans->Read(buf.get(), 256, callback.callback());
4142 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224143 // Delete the first request, so the second one can reuse the socket.
4144 trans.reset();
4145
[email protected]262eec82013-03-19 21:01:364146 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504147 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224148 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504149 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224150
4151 LoadTimingInfo load_timing_info2;
4152 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4153 TestLoadTimingReused(load_timing_info2);
4154
4155 // The requests should have the same ID.
4156 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4157
mmenke11eb5152015-06-09 14:50:504158 rv = trans2->Read(buf.get(), 256, callback.callback());
4159 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224160}
4161
[email protected]2df19bb2010-08-25 20:13:464162// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024163TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464164 HttpRequestInfo request;
4165 request.method = "GET";
bncce36dca22015-04-21 22:11:234166 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464167 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294168 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464169
[email protected]79cb5c12011-09-12 13:12:044170 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074171 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:044172 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:514173 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074174 session_deps_.net_log = log.bound().net_log();
4175 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274176
[email protected]2df19bb2010-08-25 20:13:464177 // Since we have proxy, should use full url
4178 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234179 MockWrite(
4180 "GET http://www.example.org/ HTTP/1.1\r\n"
4181 "Host: www.example.org\r\n"
4182 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464183
bncce36dca22015-04-21 22:11:234184 // After calling trans->RestartWithAuth(), this is the request we should
4185 // be issuing -- the final header line contains the credentials.
4186 MockWrite(
4187 "GET http://www.example.org/ HTTP/1.1\r\n"
4188 "Host: www.example.org\r\n"
4189 "Proxy-Connection: keep-alive\r\n"
4190 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464191 };
4192
4193 // The proxy responds to the GET with a 407, using a persistent
4194 // connection.
4195 MockRead data_reads1[] = {
4196 // No credentials.
4197 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4198 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4199 MockRead("Proxy-Connection: keep-alive\r\n"),
4200 MockRead("Content-Length: 0\r\n\r\n"),
4201
4202 MockRead("HTTP/1.1 200 OK\r\n"),
4203 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4204 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064205 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464206 };
4207
4208 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4209 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074210 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064211 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074212 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464213
[email protected]49639fa2011-12-20 23:22:414214 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464215
[email protected]262eec82013-03-19 21:01:364216 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504217 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504218
[email protected]49639fa2011-12-20 23:22:414219 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464220 EXPECT_EQ(ERR_IO_PENDING, rv);
4221
4222 rv = callback1.WaitForResult();
4223 EXPECT_EQ(OK, rv);
4224
[email protected]58e32bb2013-01-21 18:23:254225 LoadTimingInfo load_timing_info;
4226 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4227 TestLoadTimingNotReused(load_timing_info,
4228 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4229
[email protected]2df19bb2010-08-25 20:13:464230 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504231 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504232 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464233 EXPECT_EQ(407, response->headers->response_code());
4234 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044235 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464236
[email protected]49639fa2011-12-20 23:22:414237 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464238
[email protected]49639fa2011-12-20 23:22:414239 rv = trans->RestartWithAuth(
4240 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464241 EXPECT_EQ(ERR_IO_PENDING, rv);
4242
4243 rv = callback2.WaitForResult();
4244 EXPECT_EQ(OK, rv);
4245
[email protected]58e32bb2013-01-21 18:23:254246 load_timing_info = LoadTimingInfo();
4247 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4248 // Retrying with HTTP AUTH is considered to be reusing a socket.
4249 TestLoadTimingReused(load_timing_info);
4250
[email protected]2df19bb2010-08-25 20:13:464251 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504252 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464253
4254 EXPECT_TRUE(response->headers->IsKeepAlive());
4255 EXPECT_EQ(200, response->headers->response_code());
4256 EXPECT_EQ(100, response->headers->GetContentLength());
4257 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4258
4259 // The password prompt info should not be set.
4260 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4261}
4262
[email protected]23e482282013-06-14 16:08:024263void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084264 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424265 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084266 request.method = "GET";
bncce36dca22015-04-21 22:11:234267 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084268 request.load_flags = 0;
4269
[email protected]cb9bf6ca2011-01-28 13:15:274270 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074271 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:074272 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274273
[email protected]c744cf22009-02-27 07:28:084274 // Since we have proxy, should try to establish tunnel.
4275 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234276 MockWrite(
4277 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4278 "Host: www.example.org\r\n"
4279 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084280 };
4281
4282 MockRead data_reads[] = {
4283 status,
4284 MockRead("Content-Length: 10\r\n\r\n"),
4285 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064286 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084287 };
4288
[email protected]31a2bfe2010-02-09 08:03:394289 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4290 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074291 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084292
[email protected]49639fa2011-12-20 23:22:414293 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084294
[email protected]262eec82013-03-19 21:01:364295 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504296 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504297
[email protected]49639fa2011-12-20 23:22:414298 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424299 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084300
4301 rv = callback.WaitForResult();
4302 EXPECT_EQ(expected_status, rv);
4303}
4304
[email protected]23e482282013-06-14 16:08:024305void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234306 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084307 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424308 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084309}
4310
[email protected]23e482282013-06-14 16:08:024311TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084312 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4313}
4314
[email protected]23e482282013-06-14 16:08:024315TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084316 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4317}
4318
[email protected]23e482282013-06-14 16:08:024319TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084320 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4321}
4322
[email protected]23e482282013-06-14 16:08:024323TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084324 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4325}
4326
[email protected]23e482282013-06-14 16:08:024327TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084328 ConnectStatusHelper(
4329 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4330}
4331
[email protected]23e482282013-06-14 16:08:024332TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084333 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4334}
4335
[email protected]23e482282013-06-14 16:08:024336TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084337 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4338}
4339
[email protected]23e482282013-06-14 16:08:024340TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084341 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4342}
4343
[email protected]23e482282013-06-14 16:08:024344TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084345 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4346}
4347
[email protected]23e482282013-06-14 16:08:024348TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084349 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4350}
4351
[email protected]23e482282013-06-14 16:08:024352TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084353 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4354}
4355
[email protected]23e482282013-06-14 16:08:024356TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084357 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4358}
4359
[email protected]23e482282013-06-14 16:08:024360TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084361 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4362}
4363
[email protected]23e482282013-06-14 16:08:024364TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084365 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4366}
4367
[email protected]23e482282013-06-14 16:08:024368TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084369 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4370}
4371
[email protected]23e482282013-06-14 16:08:024372TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084373 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4374}
4375
[email protected]0a17aab32014-04-24 03:32:374376TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4377 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4378}
4379
[email protected]23e482282013-06-14 16:08:024380TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084381 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4382}
4383
[email protected]23e482282013-06-14 16:08:024384TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084385 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4386}
4387
[email protected]23e482282013-06-14 16:08:024388TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084389 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4390}
4391
[email protected]23e482282013-06-14 16:08:024392TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084393 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4394}
4395
[email protected]23e482282013-06-14 16:08:024396TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084397 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4398}
4399
[email protected]23e482282013-06-14 16:08:024400TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084401 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4402}
4403
[email protected]23e482282013-06-14 16:08:024404TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084405 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4406}
4407
[email protected]23e482282013-06-14 16:08:024408TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084409 ConnectStatusHelperWithExpectedStatus(
4410 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544411 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084412}
4413
[email protected]23e482282013-06-14 16:08:024414TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084415 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4416}
4417
[email protected]23e482282013-06-14 16:08:024418TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084419 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4420}
4421
[email protected]23e482282013-06-14 16:08:024422TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084423 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4424}
4425
[email protected]23e482282013-06-14 16:08:024426TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084427 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4428}
4429
[email protected]23e482282013-06-14 16:08:024430TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084431 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4432}
4433
[email protected]23e482282013-06-14 16:08:024434TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084435 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4436}
4437
[email protected]23e482282013-06-14 16:08:024438TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084439 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4440}
4441
[email protected]23e482282013-06-14 16:08:024442TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084443 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4444}
4445
[email protected]23e482282013-06-14 16:08:024446TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084447 ConnectStatusHelper(
4448 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4449}
4450
[email protected]23e482282013-06-14 16:08:024451TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084452 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4453}
4454
[email protected]23e482282013-06-14 16:08:024455TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084456 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4457}
4458
[email protected]23e482282013-06-14 16:08:024459TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084460 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4461}
4462
[email protected]23e482282013-06-14 16:08:024463TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084464 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4465}
4466
[email protected]23e482282013-06-14 16:08:024467TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084468 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4469}
4470
[email protected]23e482282013-06-14 16:08:024471TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084472 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4473}
4474
[email protected]23e482282013-06-14 16:08:024475TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084476 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4477}
4478
[email protected]038e9a32008-10-08 22:40:164479// Test the flow when both the proxy server AND origin server require
4480// authentication. Again, this uses basic auth for both since that is
4481// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024482TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274483 HttpRequestInfo request;
4484 request.method = "GET";
bncce36dca22015-04-21 22:11:234485 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274486 request.load_flags = 0;
4487
[email protected]038e9a32008-10-08 22:40:164488 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074489 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4490 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4491
4492 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414493 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164494
[email protected]f9ee6b52008-11-08 06:46:234495 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234496 MockWrite(
4497 "GET http://www.example.org/ HTTP/1.1\r\n"
4498 "Host: www.example.org\r\n"
4499 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:234500 };
4501
[email protected]038e9a32008-10-08 22:40:164502 MockRead data_reads1[] = {
4503 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4504 // Give a couple authenticate options (only the middle one is actually
4505 // supported).
[email protected]22927ad2009-09-21 19:56:194506 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164507 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4508 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4509 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4510 // Large content-length -- won't matter, as connection will be reset.
4511 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064512 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164513 };
4514
4515 // After calling trans->RestartWithAuth() the first time, this is the
4516 // request we should be issuing -- the final header line contains the
4517 // proxy's credentials.
4518 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:234519 MockWrite(
4520 "GET http://www.example.org/ HTTP/1.1\r\n"
4521 "Host: www.example.org\r\n"
4522 "Proxy-Connection: keep-alive\r\n"
4523 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164524 };
4525
4526 // Now the proxy server lets the request pass through to origin server.
4527 // The origin server responds with a 401.
4528 MockRead data_reads2[] = {
4529 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4530 // Note: We are using the same realm-name as the proxy server. This is
4531 // completely valid, as realms are unique across hosts.
4532 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4534 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064535 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164536 };
4537
4538 // After calling trans->RestartWithAuth() the second time, we should send
4539 // the credentials for both the proxy and origin server.
4540 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:234541 MockWrite(
4542 "GET http://www.example.org/ HTTP/1.1\r\n"
4543 "Host: www.example.org\r\n"
4544 "Proxy-Connection: keep-alive\r\n"
4545 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4546 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164547 };
4548
4549 // Lastly we get the desired content.
4550 MockRead data_reads3[] = {
4551 MockRead("HTTP/1.0 200 OK\r\n"),
4552 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4553 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064554 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164555 };
4556
[email protected]31a2bfe2010-02-09 08:03:394557 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4558 data_writes1, arraysize(data_writes1));
4559 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4560 data_writes2, arraysize(data_writes2));
4561 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4562 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074563 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4564 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4565 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164566
[email protected]49639fa2011-12-20 23:22:414567 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164568
[email protected]49639fa2011-12-20 23:22:414569 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424570 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164571
4572 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424573 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164574
[email protected]1c773ea12009-04-28 19:58:424575 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504576 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044577 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164578
[email protected]49639fa2011-12-20 23:22:414579 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164580
[email protected]49639fa2011-12-20 23:22:414581 rv = trans->RestartWithAuth(
4582 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424583 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164584
4585 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424586 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164587
4588 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504589 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044590 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164591
[email protected]49639fa2011-12-20 23:22:414592 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164593
[email protected]49639fa2011-12-20 23:22:414594 rv = trans->RestartWithAuth(
4595 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424596 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164597
4598 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424599 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164600
4601 response = trans->GetResponseInfo();
4602 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4603 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164604}
[email protected]4ddaf2502008-10-23 18:26:194605
[email protected]ea9dc9a2009-09-05 00:43:324606// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4607// can't hook into its internals to cause it to generate predictable NTLM
4608// authorization headers.
4609#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294610// The NTLM authentication unit tests were generated by capturing the HTTP
4611// requests and responses using Fiddler 2 and inspecting the generated random
4612// bytes in the debugger.
4613
4614// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024615TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424616 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244617 request.method = "GET";
4618 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544619
4620 // Ensure load is not disrupted by flags which suppress behaviour specific
4621 // to other auth schemes.
4622 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244623
[email protected]cb9bf6ca2011-01-28 13:15:274624 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4625 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074626 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274627
[email protected]3f918782009-02-28 01:29:244628 MockWrite data_writes1[] = {
4629 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4630 "Host: 172.22.68.17\r\n"
4631 "Connection: keep-alive\r\n\r\n"),
4632 };
4633
4634 MockRead data_reads1[] = {
4635 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044636 // Negotiate and NTLM are often requested together. However, we only want
4637 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4638 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244639 MockRead("WWW-Authenticate: NTLM\r\n"),
4640 MockRead("Connection: close\r\n"),
4641 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364642 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244643 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064644 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244645 };
4646
4647 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224648 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244649 // request we should be issuing -- the final header line contains a Type
4650 // 1 message.
4651 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4652 "Host: 172.22.68.17\r\n"
4653 "Connection: keep-alive\r\n"
4654 "Authorization: NTLM "
4655 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4656
4657 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4658 // (the credentials for the origin server). The second request continues
4659 // on the same connection.
4660 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4661 "Host: 172.22.68.17\r\n"
4662 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294663 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4664 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4665 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4666 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4667 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244668 };
4669
4670 MockRead data_reads2[] = {
4671 // The origin server responds with a Type 2 message.
4672 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4673 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294674 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244675 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4676 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4677 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4678 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4679 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4680 "BtAAAAAAA=\r\n"),
4681 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364682 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244683 MockRead("You are not authorized to view this page\r\n"),
4684
4685 // Lastly we get the desired content.
4686 MockRead("HTTP/1.1 200 OK\r\n"),
4687 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4688 MockRead("Content-Length: 13\r\n\r\n"),
4689 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064690 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244691 };
4692
[email protected]31a2bfe2010-02-09 08:03:394693 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4694 data_writes1, arraysize(data_writes1));
4695 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4696 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074697 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4698 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244699
[email protected]49639fa2011-12-20 23:22:414700 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244701
[email protected]262eec82013-03-19 21:01:364702 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504703 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504704
[email protected]49639fa2011-12-20 23:22:414705 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424706 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244707
4708 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424709 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244710
[email protected]0757e7702009-03-27 04:00:224711 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4712
[email protected]1c773ea12009-04-28 19:58:424713 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044714 ASSERT_FALSE(response == NULL);
4715 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244716
[email protected]49639fa2011-12-20 23:22:414717 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254718
[email protected]f3cf9802011-10-28 18:44:584719 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414720 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254721 EXPECT_EQ(ERR_IO_PENDING, rv);
4722
4723 rv = callback2.WaitForResult();
4724 EXPECT_EQ(OK, rv);
4725
4726 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4727
4728 response = trans->GetResponseInfo();
4729 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254730 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4731
[email protected]49639fa2011-12-20 23:22:414732 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244733
[email protected]49639fa2011-12-20 23:22:414734 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424735 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244736
[email protected]0757e7702009-03-27 04:00:224737 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424738 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244739
4740 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504741 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244742 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4743 EXPECT_EQ(13, response->headers->GetContentLength());
4744}
4745
[email protected]385a4672009-03-11 22:21:294746// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024747TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424748 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294749 request.method = "GET";
4750 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4751 request.load_flags = 0;
4752
[email protected]cb9bf6ca2011-01-28 13:15:274753 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4754 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074755 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274756
[email protected]385a4672009-03-11 22:21:294757 MockWrite data_writes1[] = {
4758 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4759 "Host: 172.22.68.17\r\n"
4760 "Connection: keep-alive\r\n\r\n"),
4761 };
4762
4763 MockRead data_reads1[] = {
4764 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044765 // Negotiate and NTLM are often requested together. However, we only want
4766 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4767 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294768 MockRead("WWW-Authenticate: NTLM\r\n"),
4769 MockRead("Connection: close\r\n"),
4770 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364771 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294772 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064773 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294774 };
4775
4776 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224777 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294778 // request we should be issuing -- the final header line contains a Type
4779 // 1 message.
4780 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4781 "Host: 172.22.68.17\r\n"
4782 "Connection: keep-alive\r\n"
4783 "Authorization: NTLM "
4784 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4785
4786 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4787 // (the credentials for the origin server). The second request continues
4788 // on the same connection.
4789 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4790 "Host: 172.22.68.17\r\n"
4791 "Connection: keep-alive\r\n"
4792 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4793 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4794 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4795 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4796 "4Ww7b7E=\r\n\r\n"),
4797 };
4798
4799 MockRead data_reads2[] = {
4800 // The origin server responds with a Type 2 message.
4801 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4802 MockRead("WWW-Authenticate: NTLM "
4803 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4804 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4805 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4806 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4807 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4808 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4809 "BtAAAAAAA=\r\n"),
4810 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364811 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294812 MockRead("You are not authorized to view this page\r\n"),
4813
4814 // Wrong password.
4815 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294816 MockRead("WWW-Authenticate: NTLM\r\n"),
4817 MockRead("Connection: close\r\n"),
4818 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364819 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294820 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064821 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294822 };
4823
4824 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224825 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294826 // request we should be issuing -- the final header line contains a Type
4827 // 1 message.
4828 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4829 "Host: 172.22.68.17\r\n"
4830 "Connection: keep-alive\r\n"
4831 "Authorization: NTLM "
4832 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4833
4834 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4835 // (the credentials for the origin server). The second request continues
4836 // on the same connection.
4837 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4838 "Host: 172.22.68.17\r\n"
4839 "Connection: keep-alive\r\n"
4840 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4841 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4842 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4843 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4844 "+4MUm7c=\r\n\r\n"),
4845 };
4846
4847 MockRead data_reads3[] = {
4848 // The origin server responds with a Type 2 message.
4849 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4850 MockRead("WWW-Authenticate: NTLM "
4851 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4852 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4853 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4854 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4855 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4856 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4857 "BtAAAAAAA=\r\n"),
4858 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364859 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294860 MockRead("You are not authorized to view this page\r\n"),
4861
4862 // Lastly we get the desired content.
4863 MockRead("HTTP/1.1 200 OK\r\n"),
4864 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4865 MockRead("Content-Length: 13\r\n\r\n"),
4866 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064867 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294868 };
4869
[email protected]31a2bfe2010-02-09 08:03:394870 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4871 data_writes1, arraysize(data_writes1));
4872 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4873 data_writes2, arraysize(data_writes2));
4874 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4875 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074876 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4877 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4878 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294879
[email protected]49639fa2011-12-20 23:22:414880 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294881
[email protected]262eec82013-03-19 21:01:364882 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504883 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504884
[email protected]49639fa2011-12-20 23:22:414885 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424886 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294887
4888 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424889 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294890
[email protected]0757e7702009-03-27 04:00:224891 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:294892
[email protected]1c773ea12009-04-28 19:58:424893 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504894 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044895 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:294896
[email protected]49639fa2011-12-20 23:22:414897 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:294898
[email protected]0757e7702009-03-27 04:00:224899 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:584900 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:414901 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424902 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294903
[email protected]10af5fe72011-01-31 16:17:254904 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424905 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:294906
[email protected]0757e7702009-03-27 04:00:224907 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:414908 TestCompletionCallback callback3;
4909 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424910 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:254911 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424912 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224913 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4914
4915 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044916 ASSERT_FALSE(response == NULL);
4917 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:224918
[email protected]49639fa2011-12-20 23:22:414919 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:224920
4921 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:584922 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414923 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:254924 EXPECT_EQ(ERR_IO_PENDING, rv);
4925
4926 rv = callback4.WaitForResult();
4927 EXPECT_EQ(OK, rv);
4928
4929 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4930
[email protected]49639fa2011-12-20 23:22:414931 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:254932
4933 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:414934 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:424935 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:224936
4937 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424938 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:224939
[email protected]385a4672009-03-11 22:21:294940 response = trans->GetResponseInfo();
4941 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4942 EXPECT_EQ(13, response->headers->GetContentLength());
4943}
[email protected]ea9dc9a2009-09-05 00:43:324944#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:294945
[email protected]4ddaf2502008-10-23 18:26:194946// Test reading a server response which has only headers, and no body.
4947// After some maximum number of bytes is consumed, the transaction should
4948// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:024949TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:424950 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:194951 request.method = "GET";
bncce36dca22015-04-21 22:11:234952 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:194953 request.load_flags = 0;
4954
[email protected]3fe8d2f82013-10-17 08:56:074955 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274956 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414957 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:274958
[email protected]b75b7b2f2009-10-06 00:54:534959 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:434960 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:534961 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:194962
4963 MockRead data_reads[] = {
4964 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:064965 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:194966 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:064967 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:194968 };
[email protected]31a2bfe2010-02-09 08:03:394969 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:074970 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:194971
[email protected]49639fa2011-12-20 23:22:414972 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:194973
[email protected]49639fa2011-12-20 23:22:414974 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424975 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:194976
4977 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424978 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:194979}
[email protected]f4e426b2008-11-05 00:24:494980
4981// Make sure that we don't try to reuse a TCPClientSocket when failing to
4982// establish tunnel.
4983// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:024984TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:234985 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:274986 HttpRequestInfo request;
4987 request.method = "GET";
bncce36dca22015-04-21 22:11:234988 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274989 request.load_flags = 0;
4990
[email protected]f4e426b2008-11-05 00:24:494991 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074992 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:014993
[email protected]bb88e1d32013-05-03 23:11:074994 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:494995
[email protected]262eec82013-03-19 21:01:364996 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504997 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:494998
[email protected]f4e426b2008-11-05 00:24:494999 // Since we have proxy, should try to establish tunnel.
5000 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235001 MockWrite(
5002 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5003 "Host: www.example.org\r\n"
5004 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495005 };
5006
[email protected]77848d12008-11-14 00:00:225007 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495008 // connection. Usually a proxy would return 501 (not implemented),
5009 // or 200 (tunnel established).
5010 MockRead data_reads1[] = {
5011 MockRead("HTTP/1.1 404 Not Found\r\n"),
5012 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065013 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495014 };
5015
[email protected]31a2bfe2010-02-09 08:03:395016 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5017 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075018 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495019
[email protected]49639fa2011-12-20 23:22:415020 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495021
[email protected]49639fa2011-12-20 23:22:415022 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425023 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495024
5025 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425026 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495027
[email protected]b4404c02009-04-10 16:38:525028 // Empty the current queue. This is necessary because idle sockets are
5029 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345030 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525031
[email protected]f4e426b2008-11-05 00:24:495032 // We now check to make sure the TCPClientSocket was not added back to
5033 // the pool.
[email protected]90499482013-06-01 00:39:505034 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495035 trans.reset();
[email protected]2da659e2013-05-23 20:51:345036 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495037 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505038 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495039}
[email protected]372d34a2008-11-05 21:30:515040
[email protected]1b157c02009-04-21 01:55:405041// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025042TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425043 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405044 request.method = "GET";
bncce36dca22015-04-21 22:11:235045 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405046 request.load_flags = 0;
5047
[email protected]bb88e1d32013-05-03 23:11:075048 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275049
[email protected]262eec82013-03-19 21:01:365050 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505051 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275052
[email protected]1b157c02009-04-21 01:55:405053 MockRead data_reads[] = {
5054 // A part of the response body is received with the response headers.
5055 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5056 // The rest of the response body is received in two parts.
5057 MockRead("lo"),
5058 MockRead(" world"),
5059 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065060 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405061 };
5062
[email protected]31a2bfe2010-02-09 08:03:395063 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075064 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405065
[email protected]49639fa2011-12-20 23:22:415066 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405067
[email protected]49639fa2011-12-20 23:22:415068 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425069 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405070
5071 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425072 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405073
[email protected]1c773ea12009-04-28 19:58:425074 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505075 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405076
[email protected]90499482013-06-01 00:39:505077 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405078 std::string status_line = response->headers->GetStatusLine();
5079 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5080
[email protected]90499482013-06-01 00:39:505081 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405082
5083 std::string response_data;
5084 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425085 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405086 EXPECT_EQ("hello world", response_data);
5087
5088 // Empty the current queue. This is necessary because idle sockets are
5089 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345090 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405091
5092 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505093 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405094}
5095
[email protected]76a505b2010-08-25 06:23:005096// Make sure that we recycle a SSL socket after reading all of the response
5097// body.
[email protected]23e482282013-06-14 16:08:025098TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005099 HttpRequestInfo request;
5100 request.method = "GET";
bncce36dca22015-04-21 22:11:235101 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005102 request.load_flags = 0;
5103
5104 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235105 MockWrite(
5106 "GET / HTTP/1.1\r\n"
5107 "Host: www.example.org\r\n"
5108 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005109 };
5110
5111 MockRead data_reads[] = {
5112 MockRead("HTTP/1.1 200 OK\r\n"),
5113 MockRead("Content-Length: 11\r\n\r\n"),
5114 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065115 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005116 };
5117
[email protected]8ddf8322012-02-23 18:08:065118 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075119 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005120
5121 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5122 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075123 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005124
[email protected]49639fa2011-12-20 23:22:415125 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005126
[email protected]bb88e1d32013-05-03 23:11:075127 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365128 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505129 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005130
[email protected]49639fa2011-12-20 23:22:415131 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005132
5133 EXPECT_EQ(ERR_IO_PENDING, rv);
5134 EXPECT_EQ(OK, callback.WaitForResult());
5135
5136 const HttpResponseInfo* response = trans->GetResponseInfo();
5137 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505138 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005139 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5140
[email protected]90499482013-06-01 00:39:505141 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005142
5143 std::string response_data;
5144 rv = ReadTransaction(trans.get(), &response_data);
5145 EXPECT_EQ(OK, rv);
5146 EXPECT_EQ("hello world", response_data);
5147
5148 // Empty the current queue. This is necessary because idle sockets are
5149 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345150 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005151
5152 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505153 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005154}
5155
5156// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5157// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025158TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005159 HttpRequestInfo request;
5160 request.method = "GET";
bncce36dca22015-04-21 22:11:235161 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005162 request.load_flags = 0;
5163
5164 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235165 MockWrite(
5166 "GET / HTTP/1.1\r\n"
5167 "Host: www.example.org\r\n"
5168 "Connection: keep-alive\r\n\r\n"),
5169 MockWrite(
5170 "GET / HTTP/1.1\r\n"
5171 "Host: www.example.org\r\n"
5172 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005173 };
5174
5175 MockRead data_reads[] = {
5176 MockRead("HTTP/1.1 200 OK\r\n"),
5177 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065178 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005179 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065180 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005181 };
5182
[email protected]8ddf8322012-02-23 18:08:065183 SSLSocketDataProvider ssl(ASYNC, OK);
5184 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075185 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5186 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005187
5188 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5189 data_writes, arraysize(data_writes));
5190 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5191 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075192 session_deps_.socket_factory->AddSocketDataProvider(&data);
5193 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005194
[email protected]49639fa2011-12-20 23:22:415195 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005196
[email protected]bb88e1d32013-05-03 23:11:075197 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365198 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005200
[email protected]49639fa2011-12-20 23:22:415201 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005202
5203 EXPECT_EQ(ERR_IO_PENDING, rv);
5204 EXPECT_EQ(OK, callback.WaitForResult());
5205
5206 const HttpResponseInfo* response = trans->GetResponseInfo();
5207 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505208 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005209 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5210
[email protected]90499482013-06-01 00:39:505211 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005212
5213 std::string response_data;
5214 rv = ReadTransaction(trans.get(), &response_data);
5215 EXPECT_EQ(OK, rv);
5216 EXPECT_EQ("hello world", response_data);
5217
5218 // Empty the current queue. This is necessary because idle sockets are
5219 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345220 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005221
5222 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505223 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005224
5225 // Now start the second transaction, which should reuse the previous socket.
5226
[email protected]90499482013-06-01 00:39:505227 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005228
[email protected]49639fa2011-12-20 23:22:415229 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005230
5231 EXPECT_EQ(ERR_IO_PENDING, rv);
5232 EXPECT_EQ(OK, callback.WaitForResult());
5233
5234 response = trans->GetResponseInfo();
5235 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505236 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005237 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5238
[email protected]90499482013-06-01 00:39:505239 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005240
5241 rv = ReadTransaction(trans.get(), &response_data);
5242 EXPECT_EQ(OK, rv);
5243 EXPECT_EQ("hello world", response_data);
5244
5245 // Empty the current queue. This is necessary because idle sockets are
5246 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345247 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005248
5249 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505250 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005251}
5252
[email protected]b4404c02009-04-10 16:38:525253// Make sure that we recycle a socket after a zero-length response.
5254// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025255TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425256 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525257 request.method = "GET";
bncce36dca22015-04-21 22:11:235258 request.url = GURL(
5259 "http://www.example.org/csi?v=3&s=web&action=&"
5260 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5261 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5262 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525263 request.load_flags = 0;
5264
[email protected]bb88e1d32013-05-03 23:11:075265 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275266
[email protected]262eec82013-03-19 21:01:365267 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505268 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275269
[email protected]b4404c02009-04-10 16:38:525270 MockRead data_reads[] = {
5271 MockRead("HTTP/1.1 204 No Content\r\n"
5272 "Content-Length: 0\r\n"
5273 "Content-Type: text/html\r\n\r\n"),
5274 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065275 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525276 };
5277
[email protected]31a2bfe2010-02-09 08:03:395278 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075279 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525280
[email protected]49639fa2011-12-20 23:22:415281 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525282
[email protected]49639fa2011-12-20 23:22:415283 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425284 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525285
5286 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425287 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525288
[email protected]1c773ea12009-04-28 19:58:425289 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505290 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525291
[email protected]90499482013-06-01 00:39:505292 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525293 std::string status_line = response->headers->GetStatusLine();
5294 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5295
[email protected]90499482013-06-01 00:39:505296 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525297
5298 std::string response_data;
5299 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425300 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525301 EXPECT_EQ("", response_data);
5302
5303 // Empty the current queue. This is necessary because idle sockets are
5304 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345305 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525306
5307 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505308 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525309}
5310
[email protected]23e482282013-06-14 16:08:025311TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065312 ScopedVector<UploadElementReader> element_readers;
5313 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075314 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275315
[email protected]1c773ea12009-04-28 19:58:425316 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515317 // Transaction 1: a GET request that succeeds. The socket is recycled
5318 // after use.
5319 request[0].method = "GET";
5320 request[0].url = GURL("http://www.google.com/");
5321 request[0].load_flags = 0;
5322 // Transaction 2: a POST request. Reuses the socket kept alive from
5323 // transaction 1. The first attempts fails when writing the POST data.
5324 // This causes the transaction to retry with a new socket. The second
5325 // attempt succeeds.
5326 request[1].method = "POST";
5327 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275328 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515329 request[1].load_flags = 0;
5330
[email protected]bb88e1d32013-05-03 23:11:075331 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515332
5333 // The first socket is used for transaction 1 and the first attempt of
5334 // transaction 2.
5335
5336 // The response of transaction 1.
5337 MockRead data_reads1[] = {
5338 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5339 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065340 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515341 };
5342 // The mock write results of transaction 1 and the first attempt of
5343 // transaction 2.
5344 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065345 MockWrite(SYNCHRONOUS, 64), // GET
5346 MockWrite(SYNCHRONOUS, 93), // POST
5347 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515348 };
[email protected]31a2bfe2010-02-09 08:03:395349 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5350 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515351
5352 // The second socket is used for the second attempt of transaction 2.
5353
5354 // The response of transaction 2.
5355 MockRead data_reads2[] = {
5356 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5357 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065358 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515359 };
5360 // The mock write results of the second attempt of transaction 2.
5361 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065362 MockWrite(SYNCHRONOUS, 93), // POST
5363 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515364 };
[email protected]31a2bfe2010-02-09 08:03:395365 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5366 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515367
[email protected]bb88e1d32013-05-03 23:11:075368 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5369 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515370
thestig9d3bb0c2015-01-24 00:49:515371 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515372 "hello world", "welcome"
5373 };
5374
5375 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425376 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505377 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515378
[email protected]49639fa2011-12-20 23:22:415379 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515380
[email protected]49639fa2011-12-20 23:22:415381 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425382 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515383
5384 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425385 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515386
[email protected]1c773ea12009-04-28 19:58:425387 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505388 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515389
[email protected]90499482013-06-01 00:39:505390 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515391 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5392
5393 std::string response_data;
5394 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425395 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515396 EXPECT_EQ(kExpectedResponseData[i], response_data);
5397 }
5398}
[email protected]f9ee6b52008-11-08 06:46:235399
5400// Test the request-challenge-retry sequence for basic auth when there is
5401// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165402// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025403TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425404 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235405 request.method = "GET";
bncce36dca22015-04-21 22:11:235406 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415407 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295408
[email protected]3fe8d2f82013-10-17 08:56:075409 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275410 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415411 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275412
[email protected]a97cca42009-08-14 01:00:295413 // The password contains an escaped character -- for this test to pass it
5414 // will need to be unescaped by HttpNetworkTransaction.
5415 EXPECT_EQ("b%40r", request.url.password());
5416
[email protected]f9ee6b52008-11-08 06:46:235417 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235418 MockWrite(
5419 "GET / HTTP/1.1\r\n"
5420 "Host: www.example.org\r\n"
5421 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235422 };
5423
5424 MockRead data_reads1[] = {
5425 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5426 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5427 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065428 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235429 };
5430
[email protected]2262e3a2012-05-22 16:08:165431 // After the challenge above, the transaction will be restarted using the
5432 // identity from the url (foo, b@r) to answer the challenge.
5433 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235434 MockWrite(
5435 "GET / HTTP/1.1\r\n"
5436 "Host: www.example.org\r\n"
5437 "Connection: keep-alive\r\n"
5438 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165439 };
5440
5441 MockRead data_reads2[] = {
5442 MockRead("HTTP/1.0 200 OK\r\n"),
5443 MockRead("Content-Length: 100\r\n\r\n"),
5444 MockRead(SYNCHRONOUS, OK),
5445 };
5446
[email protected]31a2bfe2010-02-09 08:03:395447 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5448 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165449 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5450 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075451 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5452 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235453
[email protected]49639fa2011-12-20 23:22:415454 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415455 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425456 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235457 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425458 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165459 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5460
5461 TestCompletionCallback callback2;
5462 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5463 EXPECT_EQ(ERR_IO_PENDING, rv);
5464 rv = callback2.WaitForResult();
5465 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225466 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5467
[email protected]2262e3a2012-05-22 16:08:165468 const HttpResponseInfo* response = trans->GetResponseInfo();
5469 ASSERT_TRUE(response != NULL);
5470
5471 // There is no challenge info, since the identity in URL worked.
5472 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5473
5474 EXPECT_EQ(100, response->headers->GetContentLength());
5475
5476 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345477 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165478}
5479
5480// Test the request-challenge-retry sequence for basic auth when there is an
5481// incorrect identity in the URL. The identity from the URL should be used only
5482// once.
[email protected]23e482282013-06-14 16:08:025483TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165484 HttpRequestInfo request;
5485 request.method = "GET";
5486 // Note: the URL has a username:password in it. The password "baz" is
5487 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:235488 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:165489
5490 request.load_flags = LOAD_NORMAL;
5491
[email protected]3fe8d2f82013-10-17 08:56:075492 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165493 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415494 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165495
5496 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235497 MockWrite(
5498 "GET / HTTP/1.1\r\n"
5499 "Host: www.example.org\r\n"
5500 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165501 };
5502
5503 MockRead data_reads1[] = {
5504 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5505 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5506 MockRead("Content-Length: 10\r\n\r\n"),
5507 MockRead(SYNCHRONOUS, ERR_FAILED),
5508 };
5509
5510 // After the challenge above, the transaction will be restarted using the
5511 // identity from the url (foo, baz) to answer the challenge.
5512 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235513 MockWrite(
5514 "GET / HTTP/1.1\r\n"
5515 "Host: www.example.org\r\n"
5516 "Connection: keep-alive\r\n"
5517 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165518 };
5519
5520 MockRead data_reads2[] = {
5521 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5522 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5523 MockRead("Content-Length: 10\r\n\r\n"),
5524 MockRead(SYNCHRONOUS, ERR_FAILED),
5525 };
5526
5527 // After the challenge above, the transaction will be restarted using the
5528 // identity supplied by the user (foo, bar) to answer the challenge.
5529 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235530 MockWrite(
5531 "GET / HTTP/1.1\r\n"
5532 "Host: www.example.org\r\n"
5533 "Connection: keep-alive\r\n"
5534 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165535 };
5536
5537 MockRead data_reads3[] = {
5538 MockRead("HTTP/1.0 200 OK\r\n"),
5539 MockRead("Content-Length: 100\r\n\r\n"),
5540 MockRead(SYNCHRONOUS, OK),
5541 };
5542
5543 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5544 data_writes1, arraysize(data_writes1));
5545 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5546 data_writes2, arraysize(data_writes2));
5547 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5548 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075549 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5550 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5551 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165552
5553 TestCompletionCallback callback1;
5554
5555 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5556 EXPECT_EQ(ERR_IO_PENDING, rv);
5557
5558 rv = callback1.WaitForResult();
5559 EXPECT_EQ(OK, rv);
5560
5561 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5562 TestCompletionCallback callback2;
5563 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5564 EXPECT_EQ(ERR_IO_PENDING, rv);
5565 rv = callback2.WaitForResult();
5566 EXPECT_EQ(OK, rv);
5567 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5568
5569 const HttpResponseInfo* response = trans->GetResponseInfo();
5570 ASSERT_TRUE(response != NULL);
5571 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5572
5573 TestCompletionCallback callback3;
5574 rv = trans->RestartWithAuth(
5575 AuthCredentials(kFoo, kBar), callback3.callback());
5576 EXPECT_EQ(ERR_IO_PENDING, rv);
5577 rv = callback3.WaitForResult();
5578 EXPECT_EQ(OK, rv);
5579 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5580
5581 response = trans->GetResponseInfo();
5582 ASSERT_TRUE(response != NULL);
5583
5584 // There is no challenge info, since the identity worked.
5585 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5586
5587 EXPECT_EQ(100, response->headers->GetContentLength());
5588
[email protected]ea9dc9a2009-09-05 00:43:325589 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345590 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325591}
5592
[email protected]2217aa22013-10-11 03:03:545593
5594// Test the request-challenge-retry sequence for basic auth when there is a
5595// correct identity in the URL, but its use is being suppressed. The identity
5596// from the URL should never be used.
5597TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5598 HttpRequestInfo request;
5599 request.method = "GET";
bncce36dca22015-04-21 22:11:235600 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:545601 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5602
[email protected]3fe8d2f82013-10-17 08:56:075603 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545604 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545606
5607 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235608 MockWrite(
5609 "GET / HTTP/1.1\r\n"
5610 "Host: www.example.org\r\n"
5611 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545612 };
5613
5614 MockRead data_reads1[] = {
5615 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5616 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5617 MockRead("Content-Length: 10\r\n\r\n"),
5618 MockRead(SYNCHRONOUS, ERR_FAILED),
5619 };
5620
5621 // After the challenge above, the transaction will be restarted using the
5622 // identity supplied by the user, not the one in the URL, to answer the
5623 // challenge.
5624 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235625 MockWrite(
5626 "GET / HTTP/1.1\r\n"
5627 "Host: www.example.org\r\n"
5628 "Connection: keep-alive\r\n"
5629 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545630 };
5631
5632 MockRead data_reads3[] = {
5633 MockRead("HTTP/1.0 200 OK\r\n"),
5634 MockRead("Content-Length: 100\r\n\r\n"),
5635 MockRead(SYNCHRONOUS, OK),
5636 };
5637
5638 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5639 data_writes1, arraysize(data_writes1));
5640 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5641 data_writes3, arraysize(data_writes3));
5642 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5643 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5644
5645 TestCompletionCallback callback1;
5646 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5647 EXPECT_EQ(ERR_IO_PENDING, rv);
5648 rv = callback1.WaitForResult();
5649 EXPECT_EQ(OK, rv);
5650 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5651
5652 const HttpResponseInfo* response = trans->GetResponseInfo();
5653 ASSERT_TRUE(response != NULL);
5654 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5655
5656 TestCompletionCallback callback3;
5657 rv = trans->RestartWithAuth(
5658 AuthCredentials(kFoo, kBar), callback3.callback());
5659 EXPECT_EQ(ERR_IO_PENDING, rv);
5660 rv = callback3.WaitForResult();
5661 EXPECT_EQ(OK, rv);
5662 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5663
5664 response = trans->GetResponseInfo();
5665 ASSERT_TRUE(response != NULL);
5666
5667 // There is no challenge info, since the identity worked.
5668 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5669 EXPECT_EQ(100, response->headers->GetContentLength());
5670
5671 // Empty the current queue.
5672 base::MessageLoop::current()->RunUntilIdle();
5673}
5674
[email protected]f9ee6b52008-11-08 06:46:235675// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025676TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075677 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235678
5679 // Transaction 1: authenticate (foo, bar) on MyRealm1
5680 {
[email protected]1c773ea12009-04-28 19:58:425681 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235682 request.method = "GET";
bncce36dca22015-04-21 22:11:235683 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:235684 request.load_flags = 0;
5685
[email protected]262eec82013-03-19 21:01:365686 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275688
[email protected]f9ee6b52008-11-08 06:46:235689 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235690 MockWrite(
5691 "GET /x/y/z HTTP/1.1\r\n"
5692 "Host: www.example.org\r\n"
5693 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235694 };
5695
5696 MockRead data_reads1[] = {
5697 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5698 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5699 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065700 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235701 };
5702
5703 // Resend with authorization (username=foo, password=bar)
5704 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235705 MockWrite(
5706 "GET /x/y/z HTTP/1.1\r\n"
5707 "Host: www.example.org\r\n"
5708 "Connection: keep-alive\r\n"
5709 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235710 };
5711
5712 // Sever accepts the authorization.
5713 MockRead data_reads2[] = {
5714 MockRead("HTTP/1.0 200 OK\r\n"),
5715 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065716 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235717 };
5718
[email protected]31a2bfe2010-02-09 08:03:395719 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5720 data_writes1, arraysize(data_writes1));
5721 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5722 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075723 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5724 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235725
[email protected]49639fa2011-12-20 23:22:415726 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235727
[email protected]49639fa2011-12-20 23:22:415728 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425729 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235730
5731 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425732 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235733
[email protected]1c773ea12009-04-28 19:58:425734 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505735 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045736 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235737
[email protected]49639fa2011-12-20 23:22:415738 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235739
[email protected]49639fa2011-12-20 23:22:415740 rv = trans->RestartWithAuth(
5741 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425742 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235743
5744 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425745 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235746
5747 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505748 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235749 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5750 EXPECT_EQ(100, response->headers->GetContentLength());
5751 }
5752
5753 // ------------------------------------------------------------------------
5754
5755 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5756 {
[email protected]1c773ea12009-04-28 19:58:425757 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235758 request.method = "GET";
5759 // Note that Transaction 1 was at /x/y/z, so this is in the same
5760 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:235761 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:235762 request.load_flags = 0;
5763
[email protected]262eec82013-03-19 21:01:365764 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505765 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275766
[email protected]f9ee6b52008-11-08 06:46:235767 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235768 MockWrite(
5769 "GET /x/y/a/b HTTP/1.1\r\n"
5770 "Host: www.example.org\r\n"
5771 "Connection: keep-alive\r\n"
5772 // Send preemptive authorization for MyRealm1
5773 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235774 };
5775
5776 // The server didn't like the preemptive authorization, and
5777 // challenges us for a different realm (MyRealm2).
5778 MockRead data_reads1[] = {
5779 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5780 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5781 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065782 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235783 };
5784
5785 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5786 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235787 MockWrite(
5788 "GET /x/y/a/b HTTP/1.1\r\n"
5789 "Host: www.example.org\r\n"
5790 "Connection: keep-alive\r\n"
5791 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235792 };
5793
5794 // Sever accepts the authorization.
5795 MockRead data_reads2[] = {
5796 MockRead("HTTP/1.0 200 OK\r\n"),
5797 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065798 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235799 };
5800
[email protected]31a2bfe2010-02-09 08:03:395801 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5802 data_writes1, arraysize(data_writes1));
5803 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5804 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075805 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5806 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235807
[email protected]49639fa2011-12-20 23:22:415808 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235809
[email protected]49639fa2011-12-20 23:22:415810 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425811 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235812
5813 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425814 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235815
[email protected]1c773ea12009-04-28 19:58:425816 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505817 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045818 ASSERT_TRUE(response->auth_challenge.get());
5819 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:235820 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:045821 response->auth_challenge->challenger.ToString());
5822 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5823 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235824
[email protected]49639fa2011-12-20 23:22:415825 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235826
[email protected]49639fa2011-12-20 23:22:415827 rv = trans->RestartWithAuth(
5828 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425829 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235830
5831 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425832 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235833
5834 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505835 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235836 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5837 EXPECT_EQ(100, response->headers->GetContentLength());
5838 }
5839
5840 // ------------------------------------------------------------------------
5841
5842 // Transaction 3: Resend a request in MyRealm's protection space --
5843 // succeed with preemptive authorization.
5844 {
[email protected]1c773ea12009-04-28 19:58:425845 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235846 request.method = "GET";
bncce36dca22015-04-21 22:11:235847 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:235848 request.load_flags = 0;
5849
[email protected]262eec82013-03-19 21:01:365850 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275852
[email protected]f9ee6b52008-11-08 06:46:235853 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235854 MockWrite(
5855 "GET /x/y/z2 HTTP/1.1\r\n"
5856 "Host: www.example.org\r\n"
5857 "Connection: keep-alive\r\n"
5858 // The authorization for MyRealm1 gets sent preemptively
5859 // (since the url is in the same protection space)
5860 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235861 };
5862
5863 // Sever accepts the preemptive authorization
5864 MockRead data_reads1[] = {
5865 MockRead("HTTP/1.0 200 OK\r\n"),
5866 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065867 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235868 };
5869
[email protected]31a2bfe2010-02-09 08:03:395870 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5871 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075872 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235873
[email protected]49639fa2011-12-20 23:22:415874 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235875
[email protected]49639fa2011-12-20 23:22:415876 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425877 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235878
5879 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425880 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235881
[email protected]1c773ea12009-04-28 19:58:425882 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505883 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235884
5885 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5886 EXPECT_EQ(100, response->headers->GetContentLength());
5887 }
5888
5889 // ------------------------------------------------------------------------
5890
5891 // Transaction 4: request another URL in MyRealm (however the
5892 // url is not known to belong to the protection space, so no pre-auth).
5893 {
[email protected]1c773ea12009-04-28 19:58:425894 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235895 request.method = "GET";
bncce36dca22015-04-21 22:11:235896 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:235897 request.load_flags = 0;
5898
[email protected]262eec82013-03-19 21:01:365899 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505900 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275901
[email protected]f9ee6b52008-11-08 06:46:235902 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235903 MockWrite(
5904 "GET /x/1 HTTP/1.1\r\n"
5905 "Host: www.example.org\r\n"
5906 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235907 };
5908
5909 MockRead data_reads1[] = {
5910 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5911 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5912 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065913 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235914 };
5915
5916 // Resend with authorization from MyRealm's cache.
5917 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235918 MockWrite(
5919 "GET /x/1 HTTP/1.1\r\n"
5920 "Host: www.example.org\r\n"
5921 "Connection: keep-alive\r\n"
5922 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235923 };
5924
5925 // Sever accepts the authorization.
5926 MockRead data_reads2[] = {
5927 MockRead("HTTP/1.0 200 OK\r\n"),
5928 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065929 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235930 };
5931
[email protected]31a2bfe2010-02-09 08:03:395932 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5933 data_writes1, arraysize(data_writes1));
5934 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5935 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075936 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5937 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235938
[email protected]49639fa2011-12-20 23:22:415939 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235940
[email protected]49639fa2011-12-20 23:22:415941 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425942 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235943
5944 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425945 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235946
[email protected]0757e7702009-03-27 04:00:225947 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415948 TestCompletionCallback callback2;
5949 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425950 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225951 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425952 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225953 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5954
[email protected]1c773ea12009-04-28 19:58:425955 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505956 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235957 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5958 EXPECT_EQ(100, response->headers->GetContentLength());
5959 }
5960
5961 // ------------------------------------------------------------------------
5962
5963 // Transaction 5: request a URL in MyRealm, but the server rejects the
5964 // cached identity. Should invalidate and re-prompt.
5965 {
[email protected]1c773ea12009-04-28 19:58:425966 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235967 request.method = "GET";
bncce36dca22015-04-21 22:11:235968 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:235969 request.load_flags = 0;
5970
[email protected]262eec82013-03-19 21:01:365971 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505972 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275973
[email protected]f9ee6b52008-11-08 06:46:235974 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235975 MockWrite(
5976 "GET /p/q/t HTTP/1.1\r\n"
5977 "Host: www.example.org\r\n"
5978 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235979 };
5980
5981 MockRead data_reads1[] = {
5982 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5983 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5984 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065985 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235986 };
5987
5988 // Resend with authorization from cache for MyRealm.
5989 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235990 MockWrite(
5991 "GET /p/q/t HTTP/1.1\r\n"
5992 "Host: www.example.org\r\n"
5993 "Connection: keep-alive\r\n"
5994 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235995 };
5996
5997 // Sever rejects the authorization.
5998 MockRead data_reads2[] = {
5999 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6000 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6001 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066002 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236003 };
6004
6005 // At this point we should prompt for new credentials for MyRealm.
6006 // Restart with username=foo3, password=foo4.
6007 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236008 MockWrite(
6009 "GET /p/q/t HTTP/1.1\r\n"
6010 "Host: www.example.org\r\n"
6011 "Connection: keep-alive\r\n"
6012 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236013 };
6014
6015 // Sever accepts the authorization.
6016 MockRead data_reads3[] = {
6017 MockRead("HTTP/1.0 200 OK\r\n"),
6018 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066019 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236020 };
6021
[email protected]31a2bfe2010-02-09 08:03:396022 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6023 data_writes1, arraysize(data_writes1));
6024 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6025 data_writes2, arraysize(data_writes2));
6026 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6027 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076028 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6029 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6030 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236031
[email protected]49639fa2011-12-20 23:22:416032 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236033
[email protected]49639fa2011-12-20 23:22:416034 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426035 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236036
6037 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426038 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236039
[email protected]0757e7702009-03-27 04:00:226040 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416041 TestCompletionCallback callback2;
6042 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426043 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226044 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426045 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226046 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6047
[email protected]1c773ea12009-04-28 19:58:426048 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506049 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046050 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236051
[email protected]49639fa2011-12-20 23:22:416052 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236053
[email protected]49639fa2011-12-20 23:22:416054 rv = trans->RestartWithAuth(
6055 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426056 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236057
[email protected]0757e7702009-03-27 04:00:226058 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426059 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236060
6061 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506062 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236063 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6064 EXPECT_EQ(100, response->headers->GetContentLength());
6065 }
6066}
[email protected]89ceba9a2009-03-21 03:46:066067
[email protected]3c32c5f2010-05-18 15:18:126068// Tests that nonce count increments when multiple auth attempts
6069// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026070TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446071 HttpAuthHandlerDigest::Factory* digest_factory =
6072 new HttpAuthHandlerDigest::Factory();
6073 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6074 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6075 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076076 session_deps_.http_auth_handler_factory.reset(digest_factory);
6077 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126078
6079 // Transaction 1: authenticate (foo, bar) on MyRealm1
6080 {
[email protected]3c32c5f2010-05-18 15:18:126081 HttpRequestInfo request;
6082 request.method = "GET";
bncce36dca22015-04-21 22:11:236083 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126084 request.load_flags = 0;
6085
[email protected]262eec82013-03-19 21:01:366086 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506087 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276088
[email protected]3c32c5f2010-05-18 15:18:126089 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236090 MockWrite(
6091 "GET /x/y/z HTTP/1.1\r\n"
6092 "Host: www.example.org\r\n"
6093 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126094 };
6095
6096 MockRead data_reads1[] = {
6097 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6098 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6099 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066100 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126101 };
6102
6103 // Resend with authorization (username=foo, password=bar)
6104 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236105 MockWrite(
6106 "GET /x/y/z HTTP/1.1\r\n"
6107 "Host: www.example.org\r\n"
6108 "Connection: keep-alive\r\n"
6109 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6110 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6111 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6112 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126113 };
6114
6115 // Sever accepts the authorization.
6116 MockRead data_reads2[] = {
6117 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066118 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126119 };
6120
6121 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6122 data_writes1, arraysize(data_writes1));
6123 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6124 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076125 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6126 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126127
[email protected]49639fa2011-12-20 23:22:416128 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126129
[email protected]49639fa2011-12-20 23:22:416130 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126131 EXPECT_EQ(ERR_IO_PENDING, rv);
6132
6133 rv = callback1.WaitForResult();
6134 EXPECT_EQ(OK, rv);
6135
6136 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506137 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046138 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126139
[email protected]49639fa2011-12-20 23:22:416140 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126141
[email protected]49639fa2011-12-20 23:22:416142 rv = trans->RestartWithAuth(
6143 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126144 EXPECT_EQ(ERR_IO_PENDING, rv);
6145
6146 rv = callback2.WaitForResult();
6147 EXPECT_EQ(OK, rv);
6148
6149 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506150 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126151 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6152 }
6153
6154 // ------------------------------------------------------------------------
6155
6156 // Transaction 2: Request another resource in digestive's protection space.
6157 // This will preemptively add an Authorization header which should have an
6158 // "nc" value of 2 (as compared to 1 in the first use.
6159 {
[email protected]3c32c5f2010-05-18 15:18:126160 HttpRequestInfo request;
6161 request.method = "GET";
6162 // Note that Transaction 1 was at /x/y/z, so this is in the same
6163 // protection space as digest.
bncce36dca22015-04-21 22:11:236164 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126165 request.load_flags = 0;
6166
[email protected]262eec82013-03-19 21:01:366167 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506168 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276169
[email protected]3c32c5f2010-05-18 15:18:126170 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236171 MockWrite(
6172 "GET /x/y/a/b HTTP/1.1\r\n"
6173 "Host: www.example.org\r\n"
6174 "Connection: keep-alive\r\n"
6175 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6176 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6177 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6178 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126179 };
6180
6181 // Sever accepts the authorization.
6182 MockRead data_reads1[] = {
6183 MockRead("HTTP/1.0 200 OK\r\n"),
6184 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066185 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126186 };
6187
6188 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6189 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076190 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126191
[email protected]49639fa2011-12-20 23:22:416192 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126193
[email protected]49639fa2011-12-20 23:22:416194 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126195 EXPECT_EQ(ERR_IO_PENDING, rv);
6196
6197 rv = callback1.WaitForResult();
6198 EXPECT_EQ(OK, rv);
6199
6200 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506201 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126202 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6203 }
6204}
6205
[email protected]89ceba9a2009-03-21 03:46:066206// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026207TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066208 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:076209 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406210 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066212
6213 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066214 trans->read_buf_ = new IOBuffer(15);
6215 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206216 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066217
6218 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146219 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576220 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086221 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576222 response->response_time = base::Time::Now();
6223 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066224
6225 { // Setup state for response_.vary_data
6226 HttpRequestInfo request;
6227 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6228 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276229 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436230 request.extra_headers.SetHeader("Foo", "1");
6231 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506232 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066233 }
6234
6235 // Cause the above state to be reset.
6236 trans->ResetStateForRestart();
6237
6238 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076239 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066240 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206241 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576242 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6243 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046244 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086245 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576246 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066247}
6248
[email protected]bacff652009-03-31 17:50:336249// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026250TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336251 HttpRequestInfo request;
6252 request.method = "GET";
bncce36dca22015-04-21 22:11:236253 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336254 request.load_flags = 0;
6255
[email protected]3fe8d2f82013-10-17 08:56:076256 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276257 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416258 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276259
[email protected]bacff652009-03-31 17:50:336260 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236261 MockWrite(
6262 "GET / HTTP/1.1\r\n"
6263 "Host: www.example.org\r\n"
6264 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336265 };
6266
6267 MockRead data_reads[] = {
6268 MockRead("HTTP/1.0 200 OK\r\n"),
6269 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6270 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066271 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336272 };
6273
[email protected]5ecc992a42009-11-11 01:41:596274 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396275 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6276 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066277 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6278 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336279
[email protected]bb88e1d32013-05-03 23:11:076280 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6281 session_deps_.socket_factory->AddSocketDataProvider(&data);
6282 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6283 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336284
[email protected]49639fa2011-12-20 23:22:416285 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336286
[email protected]49639fa2011-12-20 23:22:416287 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336288 EXPECT_EQ(ERR_IO_PENDING, rv);
6289
6290 rv = callback.WaitForResult();
6291 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6292
[email protected]49639fa2011-12-20 23:22:416293 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336294 EXPECT_EQ(ERR_IO_PENDING, rv);
6295
6296 rv = callback.WaitForResult();
6297 EXPECT_EQ(OK, rv);
6298
6299 const HttpResponseInfo* response = trans->GetResponseInfo();
6300
[email protected]fe2255a2011-09-20 19:37:506301 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336302 EXPECT_EQ(100, response->headers->GetContentLength());
6303}
6304
6305// Test HTTPS connections to a site with a bad certificate, going through a
6306// proxy
[email protected]23e482282013-06-14 16:08:026307TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:076308 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:336309
6310 HttpRequestInfo request;
6311 request.method = "GET";
bncce36dca22015-04-21 22:11:236312 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336313 request.load_flags = 0;
6314
6315 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:236316 MockWrite(
6317 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6318 "Host: www.example.org\r\n"
6319 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336320 };
6321
6322 MockRead proxy_reads[] = {
6323 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066324 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336325 };
6326
6327 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236328 MockWrite(
6329 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6330 "Host: www.example.org\r\n"
6331 "Proxy-Connection: keep-alive\r\n\r\n"),
6332 MockWrite(
6333 "GET / HTTP/1.1\r\n"
6334 "Host: www.example.org\r\n"
6335 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336336 };
6337
6338 MockRead data_reads[] = {
6339 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6340 MockRead("HTTP/1.0 200 OK\r\n"),
6341 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6342 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066343 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336344 };
6345
[email protected]31a2bfe2010-02-09 08:03:396346 StaticSocketDataProvider ssl_bad_certificate(
6347 proxy_reads, arraysize(proxy_reads),
6348 proxy_writes, arraysize(proxy_writes));
6349 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6350 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066351 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6352 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336353
[email protected]bb88e1d32013-05-03 23:11:076354 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6355 session_deps_.socket_factory->AddSocketDataProvider(&data);
6356 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6357 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336358
[email protected]49639fa2011-12-20 23:22:416359 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336360
6361 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076362 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336363
[email protected]3fe8d2f82013-10-17 08:56:076364 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406365 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416366 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336367
[email protected]49639fa2011-12-20 23:22:416368 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336369 EXPECT_EQ(ERR_IO_PENDING, rv);
6370
6371 rv = callback.WaitForResult();
6372 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6373
[email protected]49639fa2011-12-20 23:22:416374 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336375 EXPECT_EQ(ERR_IO_PENDING, rv);
6376
6377 rv = callback.WaitForResult();
6378 EXPECT_EQ(OK, rv);
6379
6380 const HttpResponseInfo* response = trans->GetResponseInfo();
6381
[email protected]fe2255a2011-09-20 19:37:506382 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336383 EXPECT_EQ(100, response->headers->GetContentLength());
6384 }
6385}
6386
[email protected]2df19bb2010-08-25 20:13:466387
6388// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026389TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076390 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206391 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516392 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076393 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466394
6395 HttpRequestInfo request;
6396 request.method = "GET";
bncce36dca22015-04-21 22:11:236397 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466398 request.load_flags = 0;
6399
6400 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236401 MockWrite(
6402 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6403 "Host: www.example.org\r\n"
6404 "Proxy-Connection: keep-alive\r\n\r\n"),
6405 MockWrite(
6406 "GET / HTTP/1.1\r\n"
6407 "Host: www.example.org\r\n"
6408 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466409 };
6410
6411 MockRead data_reads[] = {
6412 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6413 MockRead("HTTP/1.1 200 OK\r\n"),
6414 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6415 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066416 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466417 };
6418
6419 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6420 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066421 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6422 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466423
[email protected]bb88e1d32013-05-03 23:11:076424 session_deps_.socket_factory->AddSocketDataProvider(&data);
6425 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6426 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466427
[email protected]49639fa2011-12-20 23:22:416428 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466429
[email protected]3fe8d2f82013-10-17 08:56:076430 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466431 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416432 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466433
[email protected]49639fa2011-12-20 23:22:416434 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466435 EXPECT_EQ(ERR_IO_PENDING, rv);
6436
6437 rv = callback.WaitForResult();
6438 EXPECT_EQ(OK, rv);
6439 const HttpResponseInfo* response = trans->GetResponseInfo();
6440
[email protected]fe2255a2011-09-20 19:37:506441 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466442
6443 EXPECT_TRUE(response->headers->IsKeepAlive());
6444 EXPECT_EQ(200, response->headers->response_code());
6445 EXPECT_EQ(100, response->headers->GetContentLength());
6446 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206447
6448 LoadTimingInfo load_timing_info;
6449 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6450 TestLoadTimingNotReusedWithPac(load_timing_info,
6451 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466452}
6453
[email protected]511f6f52010-12-17 03:58:296454// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026455TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076456 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206457 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516458 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076459 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296460
6461 HttpRequestInfo request;
6462 request.method = "GET";
bncce36dca22015-04-21 22:11:236463 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296464 request.load_flags = 0;
6465
6466 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236467 MockWrite(
6468 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6469 "Host: www.example.org\r\n"
6470 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296471 };
6472
6473 MockRead data_reads[] = {
6474 MockRead("HTTP/1.1 302 Redirect\r\n"),
6475 MockRead("Location: http://login.example.com/\r\n"),
6476 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066477 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296478 };
6479
6480 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6481 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066482 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296483
[email protected]bb88e1d32013-05-03 23:11:076484 session_deps_.socket_factory->AddSocketDataProvider(&data);
6485 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296486
[email protected]49639fa2011-12-20 23:22:416487 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296488
[email protected]3fe8d2f82013-10-17 08:56:076489 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296490 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416491 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296492
[email protected]49639fa2011-12-20 23:22:416493 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296494 EXPECT_EQ(ERR_IO_PENDING, rv);
6495
6496 rv = callback.WaitForResult();
6497 EXPECT_EQ(OK, rv);
6498 const HttpResponseInfo* response = trans->GetResponseInfo();
6499
[email protected]fe2255a2011-09-20 19:37:506500 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296501
6502 EXPECT_EQ(302, response->headers->response_code());
6503 std::string url;
6504 EXPECT_TRUE(response->headers->IsRedirect(&url));
6505 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206506
6507 // In the case of redirects from proxies, HttpNetworkTransaction returns
6508 // timing for the proxy connection instead of the connection to the host,
6509 // and no send / receive times.
6510 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6511 LoadTimingInfo load_timing_info;
6512 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6513
6514 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:296515 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:206516
6517 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6518 EXPECT_LE(load_timing_info.proxy_resolve_start,
6519 load_timing_info.proxy_resolve_end);
6520 EXPECT_LE(load_timing_info.proxy_resolve_end,
6521 load_timing_info.connect_timing.connect_start);
6522 ExpectConnectTimingHasTimes(
6523 load_timing_info.connect_timing,
6524 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6525
6526 EXPECT_TRUE(load_timing_info.send_start.is_null());
6527 EXPECT_TRUE(load_timing_info.send_end.is_null());
6528 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296529}
6530
6531// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026532TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076533 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296534 ProxyService::CreateFixed("https://proxy:70"));
6535
6536 HttpRequestInfo request;
6537 request.method = "GET";
bncce36dca22015-04-21 22:11:236538 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296539 request.load_flags = 0;
6540
lgarrona91df87f2014-12-05 00:51:346541 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236542 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206543 scoped_ptr<SpdyFrame> goaway(
6544 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296545 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136546 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6547 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296548 };
6549
6550 static const char* const kExtraHeaders[] = {
6551 "location",
6552 "http://login.example.com/",
6553 };
[email protected]ff98d7f02012-03-22 21:44:196554 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026555 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296556 arraysize(kExtraHeaders)/2, 1));
6557 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136558 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:296559 };
6560
rch8e6c6c42015-05-01 14:05:136561 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6562 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066563 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026564 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296565
[email protected]bb88e1d32013-05-03 23:11:076566 session_deps_.socket_factory->AddSocketDataProvider(&data);
6567 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296568
[email protected]49639fa2011-12-20 23:22:416569 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296570
[email protected]3fe8d2f82013-10-17 08:56:076571 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296572 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416573 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296574
[email protected]49639fa2011-12-20 23:22:416575 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296576 EXPECT_EQ(ERR_IO_PENDING, rv);
6577
6578 rv = callback.WaitForResult();
6579 EXPECT_EQ(OK, rv);
6580 const HttpResponseInfo* response = trans->GetResponseInfo();
6581
[email protected]fe2255a2011-09-20 19:37:506582 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296583
6584 EXPECT_EQ(302, response->headers->response_code());
6585 std::string url;
6586 EXPECT_TRUE(response->headers->IsRedirect(&url));
6587 EXPECT_EQ("http://login.example.com/", url);
6588}
6589
[email protected]4eddbc732012-08-09 05:40:176590// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026591TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176592 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076593 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296594 ProxyService::CreateFixed("https://proxy:70"));
6595
6596 HttpRequestInfo request;
6597 request.method = "GET";
bncce36dca22015-04-21 22:11:236598 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296599 request.load_flags = 0;
6600
6601 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236602 MockWrite(
6603 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6604 "Host: www.example.org\r\n"
6605 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296606 };
6607
6608 MockRead data_reads[] = {
6609 MockRead("HTTP/1.1 404 Not Found\r\n"),
6610 MockRead("Content-Length: 23\r\n\r\n"),
6611 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066612 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296613 };
6614
6615 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6616 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066617 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296618
[email protected]bb88e1d32013-05-03 23:11:076619 session_deps_.socket_factory->AddSocketDataProvider(&data);
6620 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296621
[email protected]49639fa2011-12-20 23:22:416622 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296623
[email protected]3fe8d2f82013-10-17 08:56:076624 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296625 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416626 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296627
[email protected]49639fa2011-12-20 23:22:416628 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296629 EXPECT_EQ(ERR_IO_PENDING, rv);
6630
6631 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176632 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296633
[email protected]4eddbc732012-08-09 05:40:176634 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296635}
6636
[email protected]4eddbc732012-08-09 05:40:176637// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026638TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176639 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076640 session_deps_.proxy_service.reset(
6641 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296642
6643 HttpRequestInfo request;
6644 request.method = "GET";
bncce36dca22015-04-21 22:11:236645 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296646 request.load_flags = 0;
6647
lgarrona91df87f2014-12-05 00:51:346648 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236649 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206650 scoped_ptr<SpdyFrame> rst(
6651 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296652 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136653 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:296654 };
6655
6656 static const char* const kExtraHeaders[] = {
6657 "location",
6658 "http://login.example.com/",
6659 };
[email protected]ff98d7f02012-03-22 21:44:196660 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026661 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296662 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196663 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026664 spdy_util_.ConstructSpdyBodyFrame(
6665 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296666 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136667 CreateMockRead(*resp.get(), 1),
6668 CreateMockRead(*body.get(), 2),
6669 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296670 };
6671
rch8e6c6c42015-05-01 14:05:136672 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6673 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066674 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026675 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296676
[email protected]bb88e1d32013-05-03 23:11:076677 session_deps_.socket_factory->AddSocketDataProvider(&data);
6678 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296679
[email protected]49639fa2011-12-20 23:22:416680 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296681
[email protected]3fe8d2f82013-10-17 08:56:076682 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296683 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416684 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296685
[email protected]49639fa2011-12-20 23:22:416686 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296687 EXPECT_EQ(ERR_IO_PENDING, rv);
6688
6689 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176690 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296691
[email protected]4eddbc732012-08-09 05:40:176692 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296693}
6694
[email protected]0c5fb722012-02-28 11:50:356695// Test the request-challenge-retry sequence for basic auth, through
6696// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026697TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356698 HttpRequestInfo request;
6699 request.method = "GET";
bncce36dca22015-04-21 22:11:236700 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:356701 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296702 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:356703
6704 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076705 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206706 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516707 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076708 session_deps_.net_log = log.bound().net_log();
6709 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356710
6711 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346712 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236713 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206714 scoped_ptr<SpdyFrame> rst(
6715 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356716
6717 // After calling trans->RestartWithAuth(), this is the request we should
6718 // be issuing -- the final header line contains the credentials.
6719 const char* const kAuthCredentials[] = {
6720 "proxy-authorization", "Basic Zm9vOmJhcg==",
6721 };
[email protected]fba2dbde2013-05-24 16:09:016722 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346723 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:236724 HostPortPair("www.example.org", 443)));
6725 // fetch https://www.example.org/ via HTTP
6726 const char get[] =
6727 "GET / HTTP/1.1\r\n"
6728 "Host: www.example.org\r\n"
6729 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196730 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026731 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356732
6733 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136734 CreateMockWrite(*req, 0, ASYNC),
6735 CreateMockWrite(*rst, 2, ASYNC),
6736 CreateMockWrite(*connect2, 3),
6737 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:356738 };
6739
6740 // The proxy responds to the connect with a 407, using a persistent
6741 // connection.
thestig9d3bb0c2015-01-24 00:49:516742 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356743 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356744 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6745 };
[email protected]745aa9c2014-06-27 02:21:296746 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6747 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356748
[email protected]23e482282013-06-14 16:08:026749 scoped_ptr<SpdyFrame> conn_resp(
6750 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356751 const char resp[] = "HTTP/1.1 200 OK\r\n"
6752 "Content-Length: 5\r\n\r\n";
6753
[email protected]ff98d7f02012-03-22 21:44:196754 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026755 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196756 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026757 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356758 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136759 CreateMockRead(*conn_auth_resp, 1, ASYNC),
6760 CreateMockRead(*conn_resp, 4, ASYNC),
6761 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
6762 CreateMockRead(*wrapped_body, 7, ASYNC),
6763 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356764 };
6765
rch8e6c6c42015-05-01 14:05:136766 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6767 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076768 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356769 // Negotiate SPDY to the proxy
6770 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026771 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076772 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356773 // Vanilla SSL to the server
6774 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076775 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356776
6777 TestCompletionCallback callback1;
6778
[email protected]262eec82013-03-19 21:01:366779 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506780 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356781
6782 int rv = trans->Start(&request, callback1.callback(), log.bound());
6783 EXPECT_EQ(ERR_IO_PENDING, rv);
6784
6785 rv = callback1.WaitForResult();
6786 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:466787 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:356788 log.GetEntries(&entries);
6789 size_t pos = ExpectLogContainsSomewhere(
6790 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6791 NetLog::PHASE_NONE);
6792 ExpectLogContainsSomewhere(
6793 entries, pos,
6794 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6795 NetLog::PHASE_NONE);
6796
6797 const HttpResponseInfo* response = trans->GetResponseInfo();
6798 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506799 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356800 EXPECT_EQ(407, response->headers->response_code());
6801 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6802 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6803 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6804
6805 TestCompletionCallback callback2;
6806
6807 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6808 callback2.callback());
6809 EXPECT_EQ(ERR_IO_PENDING, rv);
6810
6811 rv = callback2.WaitForResult();
6812 EXPECT_EQ(OK, rv);
6813
6814 response = trans->GetResponseInfo();
6815 ASSERT_TRUE(response != NULL);
6816
6817 EXPECT_TRUE(response->headers->IsKeepAlive());
6818 EXPECT_EQ(200, response->headers->response_code());
6819 EXPECT_EQ(5, response->headers->GetContentLength());
6820 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6821
6822 // The password prompt info should not be set.
6823 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6824
[email protected]029c83b62013-01-24 05:28:206825 LoadTimingInfo load_timing_info;
6826 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6827 TestLoadTimingNotReusedWithPac(load_timing_info,
6828 CONNECT_TIMING_HAS_SSL_TIMES);
6829
[email protected]0c5fb722012-02-28 11:50:356830 trans.reset();
6831 session->CloseAllConnections();
6832}
6833
[email protected]7c6f7ba2012-04-03 04:09:296834// Test that an explicitly trusted SPDY proxy can push a resource from an
6835// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026836TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296837 HttpRequestInfo request;
6838 HttpRequestInfo push_request;
6839
[email protected]7c6f7ba2012-04-03 04:09:296840 request.method = "GET";
bncce36dca22015-04-21 22:11:236841 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:296842 push_request.method = "GET";
6843 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6844
[email protected]7c6f7ba2012-04-03 04:09:296845 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076846 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206847 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516848 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076849 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506850
6851 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076852 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506853
[email protected]bb88e1d32013-05-03 23:11:076854 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296855
[email protected]cdf8f7e72013-05-23 10:56:466856 scoped_ptr<SpdyFrame> stream1_syn(
6857 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296858
6859 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136860 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296861 };
6862
6863 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026864 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296865
6866 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026867 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296868
6869 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026870 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296871 0,
6872 2,
6873 1,
6874 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436875 const char kPushedData[] = "pushed";
6876 scoped_ptr<SpdyFrame> stream2_body(
6877 spdy_util_.ConstructSpdyBodyFrame(
6878 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296879
6880 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136881 CreateMockRead(*stream1_reply, 1, ASYNC),
6882 CreateMockRead(*stream2_syn, 2, ASYNC),
6883 CreateMockRead(*stream1_body, 3, ASYNC),
6884 CreateMockRead(*stream2_body, 4, ASYNC),
6885 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:296886 };
6887
rch8e6c6c42015-05-01 14:05:136888 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6889 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076890 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:296891 // Negotiate SPDY to the proxy
6892 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026893 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076894 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:296895
[email protected]262eec82013-03-19 21:01:366896 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506897 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:296898 TestCompletionCallback callback;
6899 int rv = trans->Start(&request, callback.callback(), log.bound());
6900 EXPECT_EQ(ERR_IO_PENDING, rv);
6901
6902 rv = callback.WaitForResult();
6903 EXPECT_EQ(OK, rv);
6904 const HttpResponseInfo* response = trans->GetResponseInfo();
6905
[email protected]262eec82013-03-19 21:01:366906 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:506907 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6908 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:296909 EXPECT_EQ(ERR_IO_PENDING, rv);
6910
6911 rv = callback.WaitForResult();
6912 EXPECT_EQ(OK, rv);
6913 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
6914
6915 ASSERT_TRUE(response != NULL);
6916 EXPECT_TRUE(response->headers->IsKeepAlive());
6917
6918 EXPECT_EQ(200, response->headers->response_code());
6919 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6920
6921 std::string response_data;
6922 rv = ReadTransaction(trans.get(), &response_data);
6923 EXPECT_EQ(OK, rv);
6924 EXPECT_EQ("hello!", response_data);
6925
[email protected]029c83b62013-01-24 05:28:206926 LoadTimingInfo load_timing_info;
6927 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6928 TestLoadTimingNotReusedWithPac(load_timing_info,
6929 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6930
[email protected]7c6f7ba2012-04-03 04:09:296931 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:506932 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:296933 EXPECT_EQ(200, push_response->headers->response_code());
6934
6935 rv = ReadTransaction(push_trans.get(), &response_data);
6936 EXPECT_EQ(OK, rv);
6937 EXPECT_EQ("pushed", response_data);
6938
[email protected]029c83b62013-01-24 05:28:206939 LoadTimingInfo push_load_timing_info;
6940 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
6941 TestLoadTimingReusedWithPac(push_load_timing_info);
6942 // The transactions should share a socket ID, despite being for different
6943 // origins.
6944 EXPECT_EQ(load_timing_info.socket_log_id,
6945 push_load_timing_info.socket_log_id);
6946
[email protected]7c6f7ba2012-04-03 04:09:296947 trans.reset();
6948 push_trans.reset();
6949 session->CloseAllConnections();
6950}
6951
[email protected]8c843192012-04-05 07:15:006952// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:026953TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:006954 HttpRequestInfo request;
6955
6956 request.method = "GET";
bncce36dca22015-04-21 22:11:236957 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:006958
[email protected]8c843192012-04-05 07:15:006959 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076960 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:006961 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516962 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076963 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506964
6965 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076966 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506967
[email protected]bb88e1d32013-05-03 23:11:076968 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:006969
[email protected]cdf8f7e72013-05-23 10:56:466970 scoped_ptr<SpdyFrame> stream1_syn(
6971 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:006972
6973 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:206974 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:006975
6976 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136977 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:006978 };
6979
6980 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026981 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:006982
6983 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026984 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:006985
6986 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026987 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:006988 0,
6989 2,
6990 1,
6991 "https://www.another-origin.com/foo.dat"));
6992
6993 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136994 CreateMockRead(*stream1_reply, 1, ASYNC),
6995 CreateMockRead(*stream2_syn, 2, ASYNC),
6996 CreateMockRead(*stream1_body, 4, ASYNC),
6997 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:006998 };
6999
rch8e6c6c42015-05-01 14:05:137000 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7001 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077002 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007003 // Negotiate SPDY to the proxy
7004 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027005 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077006 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007007
[email protected]262eec82013-03-19 21:01:367008 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507009 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007010 TestCompletionCallback callback;
7011 int rv = trans->Start(&request, callback.callback(), log.bound());
7012 EXPECT_EQ(ERR_IO_PENDING, rv);
7013
7014 rv = callback.WaitForResult();
7015 EXPECT_EQ(OK, rv);
7016 const HttpResponseInfo* response = trans->GetResponseInfo();
7017
7018 ASSERT_TRUE(response != NULL);
7019 EXPECT_TRUE(response->headers->IsKeepAlive());
7020
7021 EXPECT_EQ(200, response->headers->response_code());
7022 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7023
7024 std::string response_data;
7025 rv = ReadTransaction(trans.get(), &response_data);
7026 EXPECT_EQ(OK, rv);
7027 EXPECT_EQ("hello!", response_data);
7028
7029 trans.reset();
7030 session->CloseAllConnections();
7031}
7032
[email protected]2df19bb2010-08-25 20:13:467033// Test HTTPS connections to a site with a bad certificate, going through an
7034// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027035TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:077036 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:117037 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:467038
7039 HttpRequestInfo request;
7040 request.method = "GET";
bncce36dca22015-04-21 22:11:237041 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467042 request.load_flags = 0;
7043
7044 // Attempt to fetch the URL from a server with a bad cert
7045 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237046 MockWrite(
7047 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7048 "Host: www.example.org\r\n"
7049 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467050 };
7051
7052 MockRead bad_cert_reads[] = {
7053 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067054 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467055 };
7056
7057 // Attempt to fetch the URL with a good cert
7058 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237059 MockWrite(
7060 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7061 "Host: www.example.org\r\n"
7062 "Proxy-Connection: keep-alive\r\n\r\n"),
7063 MockWrite(
7064 "GET / HTTP/1.1\r\n"
7065 "Host: www.example.org\r\n"
7066 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467067 };
7068
7069 MockRead good_cert_reads[] = {
7070 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7071 MockRead("HTTP/1.0 200 OK\r\n"),
7072 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7073 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067074 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467075 };
7076
7077 StaticSocketDataProvider ssl_bad_certificate(
7078 bad_cert_reads, arraysize(bad_cert_reads),
7079 bad_cert_writes, arraysize(bad_cert_writes));
7080 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7081 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067082 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7083 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467084
7085 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077086 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7087 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7088 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467089
7090 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077091 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7092 session_deps_.socket_factory->AddSocketDataProvider(&data);
7093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467094
[email protected]49639fa2011-12-20 23:22:417095 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467096
[email protected]3fe8d2f82013-10-17 08:56:077097 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467098 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417099 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467100
[email protected]49639fa2011-12-20 23:22:417101 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467102 EXPECT_EQ(ERR_IO_PENDING, rv);
7103
7104 rv = callback.WaitForResult();
7105 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7106
[email protected]49639fa2011-12-20 23:22:417107 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467108 EXPECT_EQ(ERR_IO_PENDING, rv);
7109
7110 rv = callback.WaitForResult();
7111 EXPECT_EQ(OK, rv);
7112
7113 const HttpResponseInfo* response = trans->GetResponseInfo();
7114
[email protected]fe2255a2011-09-20 19:37:507115 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467116 EXPECT_EQ(100, response->headers->GetContentLength());
7117}
7118
[email protected]23e482282013-06-14 16:08:027119TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427120 HttpRequestInfo request;
7121 request.method = "GET";
bncce36dca22015-04-21 22:11:237122 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437123 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7124 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427125
[email protected]3fe8d2f82013-10-17 08:56:077126 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277127 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277129
[email protected]1c773ea12009-04-28 19:58:427130 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237131 MockWrite(
7132 "GET / HTTP/1.1\r\n"
7133 "Host: www.example.org\r\n"
7134 "Connection: keep-alive\r\n"
7135 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427136 };
7137
7138 // Lastly, the server responds with the actual content.
7139 MockRead data_reads[] = {
7140 MockRead("HTTP/1.0 200 OK\r\n"),
7141 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7142 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067143 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427144 };
7145
[email protected]31a2bfe2010-02-09 08:03:397146 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7147 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077148 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427149
[email protected]49639fa2011-12-20 23:22:417150 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427151
[email protected]49639fa2011-12-20 23:22:417152 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427153 EXPECT_EQ(ERR_IO_PENDING, rv);
7154
7155 rv = callback.WaitForResult();
7156 EXPECT_EQ(OK, rv);
7157}
7158
[email protected]23e482282013-06-14 16:08:027159TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297160 HttpRequestInfo request;
7161 request.method = "GET";
bncce36dca22015-04-21 22:11:237162 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297163 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7164 "Chromium Ultra Awesome X Edition");
7165
[email protected]bb88e1d32013-05-03 23:11:077166 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:077167 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277168 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417169 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277170
[email protected]da81f132010-08-18 23:39:297171 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237172 MockWrite(
7173 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7174 "Host: www.example.org\r\n"
7175 "Proxy-Connection: keep-alive\r\n"
7176 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297177 };
7178 MockRead data_reads[] = {
7179 // Return an error, so the transaction stops here (this test isn't
7180 // interested in the rest).
7181 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7182 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7183 MockRead("Proxy-Connection: close\r\n\r\n"),
7184 };
7185
7186 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7187 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077188 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297189
[email protected]49639fa2011-12-20 23:22:417190 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297191
[email protected]49639fa2011-12-20 23:22:417192 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297193 EXPECT_EQ(ERR_IO_PENDING, rv);
7194
7195 rv = callback.WaitForResult();
7196 EXPECT_EQ(OK, rv);
7197}
7198
[email protected]23e482282013-06-14 16:08:027199TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427200 HttpRequestInfo request;
7201 request.method = "GET";
bncce36dca22015-04-21 22:11:237202 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427203 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167204 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7205 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427206
[email protected]3fe8d2f82013-10-17 08:56:077207 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277208 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277210
[email protected]1c773ea12009-04-28 19:58:427211 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237212 MockWrite(
7213 "GET / HTTP/1.1\r\n"
7214 "Host: www.example.org\r\n"
7215 "Connection: keep-alive\r\n"
7216 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427217 };
7218
7219 // Lastly, the server responds with the actual content.
7220 MockRead data_reads[] = {
7221 MockRead("HTTP/1.0 200 OK\r\n"),
7222 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7223 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067224 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427225 };
7226
[email protected]31a2bfe2010-02-09 08:03:397227 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7228 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077229 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427230
[email protected]49639fa2011-12-20 23:22:417231 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427232
[email protected]49639fa2011-12-20 23:22:417233 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427234 EXPECT_EQ(ERR_IO_PENDING, rv);
7235
7236 rv = callback.WaitForResult();
7237 EXPECT_EQ(OK, rv);
7238}
7239
[email protected]23e482282013-06-14 16:08:027240TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427241 HttpRequestInfo request;
7242 request.method = "POST";
bncce36dca22015-04-21 22:11:237243 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427244
[email protected]3fe8d2f82013-10-17 08:56:077245 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277246 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277248
[email protected]1c773ea12009-04-28 19:58:427249 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237250 MockWrite(
7251 "POST / HTTP/1.1\r\n"
7252 "Host: www.example.org\r\n"
7253 "Connection: keep-alive\r\n"
7254 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427255 };
7256
7257 // Lastly, the server responds with the actual content.
7258 MockRead data_reads[] = {
7259 MockRead("HTTP/1.0 200 OK\r\n"),
7260 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7261 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067262 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427263 };
7264
[email protected]31a2bfe2010-02-09 08:03:397265 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7266 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077267 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427268
[email protected]49639fa2011-12-20 23:22:417269 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427270
[email protected]49639fa2011-12-20 23:22:417271 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427272 EXPECT_EQ(ERR_IO_PENDING, rv);
7273
7274 rv = callback.WaitForResult();
7275 EXPECT_EQ(OK, rv);
7276}
7277
[email protected]23e482282013-06-14 16:08:027278TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427279 HttpRequestInfo request;
7280 request.method = "PUT";
bncce36dca22015-04-21 22:11:237281 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427282
[email protected]3fe8d2f82013-10-17 08:56:077283 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277284 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417285 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277286
[email protected]1c773ea12009-04-28 19:58:427287 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237288 MockWrite(
7289 "PUT / HTTP/1.1\r\n"
7290 "Host: www.example.org\r\n"
7291 "Connection: keep-alive\r\n"
7292 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427293 };
7294
7295 // Lastly, the server responds with the actual content.
7296 MockRead data_reads[] = {
7297 MockRead("HTTP/1.0 200 OK\r\n"),
7298 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7299 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067300 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427301 };
7302
[email protected]31a2bfe2010-02-09 08:03:397303 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7304 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077305 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427306
[email protected]49639fa2011-12-20 23:22:417307 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427308
[email protected]49639fa2011-12-20 23:22:417309 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427310 EXPECT_EQ(ERR_IO_PENDING, rv);
7311
7312 rv = callback.WaitForResult();
7313 EXPECT_EQ(OK, rv);
7314}
7315
[email protected]23e482282013-06-14 16:08:027316TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427317 HttpRequestInfo request;
7318 request.method = "HEAD";
bncce36dca22015-04-21 22:11:237319 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427320
[email protected]3fe8d2f82013-10-17 08:56:077321 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277322 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417323 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277324
[email protected]1c773ea12009-04-28 19:58:427325 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237326 MockWrite(
7327 "HEAD / HTTP/1.1\r\n"
7328 "Host: www.example.org\r\n"
7329 "Connection: keep-alive\r\n"
7330 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427331 };
7332
7333 // Lastly, the server responds with the actual content.
7334 MockRead data_reads[] = {
7335 MockRead("HTTP/1.0 200 OK\r\n"),
7336 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7337 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067338 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427339 };
7340
[email protected]31a2bfe2010-02-09 08:03:397341 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7342 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077343 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427344
[email protected]49639fa2011-12-20 23:22:417345 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427346
[email protected]49639fa2011-12-20 23:22:417347 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427348 EXPECT_EQ(ERR_IO_PENDING, rv);
7349
7350 rv = callback.WaitForResult();
7351 EXPECT_EQ(OK, rv);
7352}
7353
[email protected]23e482282013-06-14 16:08:027354TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427355 HttpRequestInfo request;
7356 request.method = "GET";
bncce36dca22015-04-21 22:11:237357 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427358 request.load_flags = LOAD_BYPASS_CACHE;
7359
[email protected]3fe8d2f82013-10-17 08:56:077360 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277361 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417362 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277363
[email protected]1c773ea12009-04-28 19:58:427364 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237365 MockWrite(
7366 "GET / HTTP/1.1\r\n"
7367 "Host: www.example.org\r\n"
7368 "Connection: keep-alive\r\n"
7369 "Pragma: no-cache\r\n"
7370 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427371 };
7372
7373 // Lastly, the server responds with the actual content.
7374 MockRead data_reads[] = {
7375 MockRead("HTTP/1.0 200 OK\r\n"),
7376 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7377 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067378 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427379 };
7380
[email protected]31a2bfe2010-02-09 08:03:397381 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7382 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077383 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427384
[email protected]49639fa2011-12-20 23:22:417385 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427386
[email protected]49639fa2011-12-20 23:22:417387 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427388 EXPECT_EQ(ERR_IO_PENDING, rv);
7389
7390 rv = callback.WaitForResult();
7391 EXPECT_EQ(OK, rv);
7392}
7393
[email protected]23e482282013-06-14 16:08:027394TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427395 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427396 HttpRequestInfo request;
7397 request.method = "GET";
bncce36dca22015-04-21 22:11:237398 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427399 request.load_flags = LOAD_VALIDATE_CACHE;
7400
[email protected]3fe8d2f82013-10-17 08:56:077401 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277402 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417403 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277404
[email protected]1c773ea12009-04-28 19:58:427405 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237406 MockWrite(
7407 "GET / HTTP/1.1\r\n"
7408 "Host: www.example.org\r\n"
7409 "Connection: keep-alive\r\n"
7410 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427411 };
7412
7413 // Lastly, the server responds with the actual content.
7414 MockRead data_reads[] = {
7415 MockRead("HTTP/1.0 200 OK\r\n"),
7416 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7417 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067418 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427419 };
7420
[email protected]31a2bfe2010-02-09 08:03:397421 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7422 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077423 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427424
[email protected]49639fa2011-12-20 23:22:417425 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427426
[email protected]49639fa2011-12-20 23:22:417427 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427428 EXPECT_EQ(ERR_IO_PENDING, rv);
7429
7430 rv = callback.WaitForResult();
7431 EXPECT_EQ(OK, rv);
7432}
7433
[email protected]23e482282013-06-14 16:08:027434TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427435 HttpRequestInfo request;
7436 request.method = "GET";
bncce36dca22015-04-21 22:11:237437 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437438 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427439
[email protected]3fe8d2f82013-10-17 08:56:077440 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277441 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417442 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277443
[email protected]1c773ea12009-04-28 19:58:427444 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237445 MockWrite(
7446 "GET / HTTP/1.1\r\n"
7447 "Host: www.example.org\r\n"
7448 "Connection: keep-alive\r\n"
7449 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427450 };
7451
7452 // Lastly, the server responds with the actual content.
7453 MockRead data_reads[] = {
7454 MockRead("HTTP/1.0 200 OK\r\n"),
7455 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7456 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067457 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427458 };
7459
[email protected]31a2bfe2010-02-09 08:03:397460 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7461 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077462 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427463
[email protected]49639fa2011-12-20 23:22:417464 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427465
[email protected]49639fa2011-12-20 23:22:417466 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427467 EXPECT_EQ(ERR_IO_PENDING, rv);
7468
7469 rv = callback.WaitForResult();
7470 EXPECT_EQ(OK, rv);
7471}
7472
[email protected]23e482282013-06-14 16:08:027473TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477474 HttpRequestInfo request;
7475 request.method = "GET";
bncce36dca22015-04-21 22:11:237476 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437477 request.extra_headers.SetHeader("referer", "www.foo.com");
7478 request.extra_headers.SetHeader("hEllo", "Kitty");
7479 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477480
[email protected]3fe8d2f82013-10-17 08:56:077481 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277482 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417483 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277484
[email protected]270c6412010-03-29 22:02:477485 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237486 MockWrite(
7487 "GET / HTTP/1.1\r\n"
7488 "Host: www.example.org\r\n"
7489 "Connection: keep-alive\r\n"
7490 "referer: www.foo.com\r\n"
7491 "hEllo: Kitty\r\n"
7492 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:477493 };
7494
7495 // Lastly, the server responds with the actual content.
7496 MockRead data_reads[] = {
7497 MockRead("HTTP/1.0 200 OK\r\n"),
7498 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7499 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067500 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477501 };
7502
7503 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7504 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077505 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477506
[email protected]49639fa2011-12-20 23:22:417507 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477508
[email protected]49639fa2011-12-20 23:22:417509 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477510 EXPECT_EQ(ERR_IO_PENDING, rv);
7511
7512 rv = callback.WaitForResult();
7513 EXPECT_EQ(OK, rv);
7514}
7515
[email protected]23e482282013-06-14 16:08:027516TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277517 HttpRequestInfo request;
7518 request.method = "GET";
bncce36dca22015-04-21 22:11:237519 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277520 request.load_flags = 0;
7521
[email protected]bb88e1d32013-05-03 23:11:077522 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207523 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517524 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077525 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027526
[email protected]3fe8d2f82013-10-17 08:56:077527 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027528 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417529 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027530
[email protected]3cd17242009-06-23 02:59:027531 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7532 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7533
7534 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237535 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7536 MockWrite(
7537 "GET / HTTP/1.1\r\n"
7538 "Host: www.example.org\r\n"
7539 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027540
7541 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067542 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027543 MockRead("HTTP/1.0 200 OK\r\n"),
7544 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7545 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067546 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027547 };
7548
[email protected]31a2bfe2010-02-09 08:03:397549 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7550 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077551 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027552
[email protected]49639fa2011-12-20 23:22:417553 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027554
[email protected]49639fa2011-12-20 23:22:417555 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027556 EXPECT_EQ(ERR_IO_PENDING, rv);
7557
7558 rv = callback.WaitForResult();
7559 EXPECT_EQ(OK, rv);
7560
7561 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507562 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027563
[email protected]029c83b62013-01-24 05:28:207564 LoadTimingInfo load_timing_info;
7565 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7566 TestLoadTimingNotReusedWithPac(load_timing_info,
7567 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7568
[email protected]3cd17242009-06-23 02:59:027569 std::string response_text;
7570 rv = ReadTransaction(trans.get(), &response_text);
7571 EXPECT_EQ(OK, rv);
7572 EXPECT_EQ("Payload", response_text);
7573}
7574
[email protected]23e482282013-06-14 16:08:027575TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277576 HttpRequestInfo request;
7577 request.method = "GET";
bncce36dca22015-04-21 22:11:237578 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277579 request.load_flags = 0;
7580
[email protected]bb88e1d32013-05-03 23:11:077581 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207582 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517583 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077584 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027585
[email protected]3fe8d2f82013-10-17 08:56:077586 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027587 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417588 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027589
[email protected]3cd17242009-06-23 02:59:027590 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7591 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7592
7593 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237594 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7595 arraysize(write_buffer)),
7596 MockWrite(
7597 "GET / HTTP/1.1\r\n"
7598 "Host: www.example.org\r\n"
7599 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027600
7601 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017602 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7603 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357604 MockRead("HTTP/1.0 200 OK\r\n"),
7605 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7606 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067607 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357608 };
7609
[email protected]31a2bfe2010-02-09 08:03:397610 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7611 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077612 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357613
[email protected]8ddf8322012-02-23 18:08:067614 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077615 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357616
[email protected]49639fa2011-12-20 23:22:417617 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357618
[email protected]49639fa2011-12-20 23:22:417619 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357620 EXPECT_EQ(ERR_IO_PENDING, rv);
7621
7622 rv = callback.WaitForResult();
7623 EXPECT_EQ(OK, rv);
7624
[email protected]029c83b62013-01-24 05:28:207625 LoadTimingInfo load_timing_info;
7626 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7627 TestLoadTimingNotReusedWithPac(load_timing_info,
7628 CONNECT_TIMING_HAS_SSL_TIMES);
7629
[email protected]e0c27be2009-07-15 13:09:357630 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507631 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357632
7633 std::string response_text;
7634 rv = ReadTransaction(trans.get(), &response_text);
7635 EXPECT_EQ(OK, rv);
7636 EXPECT_EQ("Payload", response_text);
7637}
7638
[email protected]23e482282013-06-14 16:08:027639TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207640 HttpRequestInfo request;
7641 request.method = "GET";
bncce36dca22015-04-21 22:11:237642 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:207643 request.load_flags = 0;
7644
[email protected]bb88e1d32013-05-03 23:11:077645 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207646 ProxyService::CreateFixed("socks4://myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517647 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077648 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207649
[email protected]3fe8d2f82013-10-17 08:56:077650 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207651 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417652 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207653
7654 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7655 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7656
7657 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237658 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7659 MockWrite(
7660 "GET / HTTP/1.1\r\n"
7661 "Host: www.example.org\r\n"
7662 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:207663
7664 MockRead data_reads[] = {
7665 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7666 MockRead("HTTP/1.0 200 OK\r\n"),
7667 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7668 MockRead("Payload"),
7669 MockRead(SYNCHRONOUS, OK)
7670 };
7671
7672 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7673 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077674 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207675
7676 TestCompletionCallback callback;
7677
7678 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7679 EXPECT_EQ(ERR_IO_PENDING, rv);
7680
7681 rv = callback.WaitForResult();
7682 EXPECT_EQ(OK, rv);
7683
7684 const HttpResponseInfo* response = trans->GetResponseInfo();
7685 ASSERT_TRUE(response != NULL);
7686
7687 LoadTimingInfo load_timing_info;
7688 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7689 TestLoadTimingNotReused(load_timing_info,
7690 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7691
7692 std::string response_text;
7693 rv = ReadTransaction(trans.get(), &response_text);
7694 EXPECT_EQ(OK, rv);
7695 EXPECT_EQ("Payload", response_text);
7696}
7697
[email protected]23e482282013-06-14 16:08:027698TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277699 HttpRequestInfo request;
7700 request.method = "GET";
bncce36dca22015-04-21 22:11:237701 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277702 request.load_flags = 0;
7703
[email protected]bb88e1d32013-05-03 23:11:077704 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207705 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517706 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077707 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357708
[email protected]3fe8d2f82013-10-17 08:56:077709 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357710 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417711 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357712
[email protected]e0c27be2009-07-15 13:09:357713 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7714 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377715 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237716 0x05, // Version
7717 0x01, // Command (CONNECT)
7718 0x00, // Reserved.
7719 0x03, // Address type (DOMAINNAME).
7720 0x0F, // Length of domain (15)
7721 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7722 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:377723 };
[email protected]e0c27be2009-07-15 13:09:357724 const char kSOCKS5OkResponse[] =
7725 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7726
7727 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237728 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7729 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7730 MockWrite(
7731 "GET / HTTP/1.1\r\n"
7732 "Host: www.example.org\r\n"
7733 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357734
7735 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017736 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7737 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357738 MockRead("HTTP/1.0 200 OK\r\n"),
7739 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7740 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067741 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357742 };
7743
[email protected]31a2bfe2010-02-09 08:03:397744 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7745 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077746 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357747
[email protected]49639fa2011-12-20 23:22:417748 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357749
[email protected]49639fa2011-12-20 23:22:417750 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357751 EXPECT_EQ(ERR_IO_PENDING, rv);
7752
7753 rv = callback.WaitForResult();
7754 EXPECT_EQ(OK, rv);
7755
7756 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507757 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357758
[email protected]029c83b62013-01-24 05:28:207759 LoadTimingInfo load_timing_info;
7760 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7761 TestLoadTimingNotReusedWithPac(load_timing_info,
7762 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7763
[email protected]e0c27be2009-07-15 13:09:357764 std::string response_text;
7765 rv = ReadTransaction(trans.get(), &response_text);
7766 EXPECT_EQ(OK, rv);
7767 EXPECT_EQ("Payload", response_text);
7768}
7769
[email protected]23e482282013-06-14 16:08:027770TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277771 HttpRequestInfo request;
7772 request.method = "GET";
bncce36dca22015-04-21 22:11:237773 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277774 request.load_flags = 0;
7775
[email protected]bb88e1d32013-05-03 23:11:077776 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207777 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517778 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077779 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357780
[email protected]3fe8d2f82013-10-17 08:56:077781 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357782 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417783 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357784
[email protected]e0c27be2009-07-15 13:09:357785 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7786 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377787 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237788 0x05, // Version
7789 0x01, // Command (CONNECT)
7790 0x00, // Reserved.
7791 0x03, // Address type (DOMAINNAME).
7792 0x0F, // Length of domain (15)
7793 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7794 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:377795 };
7796
[email protected]e0c27be2009-07-15 13:09:357797 const char kSOCKS5OkResponse[] =
7798 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7799
7800 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237801 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7802 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7803 arraysize(kSOCKS5OkRequest)),
7804 MockWrite(
7805 "GET / HTTP/1.1\r\n"
7806 "Host: www.example.org\r\n"
7807 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357808
7809 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017810 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7811 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027812 MockRead("HTTP/1.0 200 OK\r\n"),
7813 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7814 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067815 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027816 };
7817
[email protected]31a2bfe2010-02-09 08:03:397818 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7819 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077820 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027821
[email protected]8ddf8322012-02-23 18:08:067822 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077823 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027824
[email protected]49639fa2011-12-20 23:22:417825 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027826
[email protected]49639fa2011-12-20 23:22:417827 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027828 EXPECT_EQ(ERR_IO_PENDING, rv);
7829
7830 rv = callback.WaitForResult();
7831 EXPECT_EQ(OK, rv);
7832
7833 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507834 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027835
[email protected]029c83b62013-01-24 05:28:207836 LoadTimingInfo load_timing_info;
7837 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7838 TestLoadTimingNotReusedWithPac(load_timing_info,
7839 CONNECT_TIMING_HAS_SSL_TIMES);
7840
[email protected]3cd17242009-06-23 02:59:027841 std::string response_text;
7842 rv = ReadTransaction(trans.get(), &response_text);
7843 EXPECT_EQ(OK, rv);
7844 EXPECT_EQ("Payload", response_text);
7845}
7846
[email protected]448d4ca52012-03-04 04:12:237847namespace {
7848
[email protected]04e5be32009-06-26 20:00:317849// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067850
7851struct GroupNameTest {
7852 std::string proxy_server;
7853 std::string url;
7854 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187855 bool ssl;
[email protected]2d731a32010-04-29 01:04:067856};
7857
7858scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437859 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077860 SpdySessionDependencies* session_deps_) {
7861 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067862
[email protected]30d4c022013-07-18 22:58:167863 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537864 session->http_server_properties();
bnccacc0992015-03-20 20:22:227865 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:257866 AlternateProtocolFromNextProto(next_proto), "", 443);
bnccacc0992015-03-20 20:22:227867 http_server_properties->SetAlternativeService(
7868 HostPortPair("host.with.alternate", 80), alternative_service, 1.0);
[email protected]2d731a32010-04-29 01:04:067869
7870 return session;
7871}
7872
7873int GroupNameTransactionHelper(
7874 const std::string& url,
7875 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067876 HttpRequestInfo request;
7877 request.method = "GET";
7878 request.url = GURL(url);
7879 request.load_flags = 0;
7880
[email protected]262eec82013-03-19 21:01:367881 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507882 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277883
[email protected]49639fa2011-12-20 23:22:417884 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067885
7886 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417887 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:067888}
7889
[email protected]448d4ca52012-03-04 04:12:237890} // namespace
7891
[email protected]23e482282013-06-14 16:08:027892TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:067893 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237894 {
7895 "", // unused
7896 "http://www.example.org/direct",
7897 "www.example.org:80",
7898 false,
7899 },
7900 {
7901 "", // unused
7902 "http://[2001:1418:13:1::25]/direct",
7903 "[2001:1418:13:1::25]:80",
7904 false,
7905 },
[email protected]04e5be32009-06-26 20:00:317906
bncce36dca22015-04-21 22:11:237907 // SSL Tests
7908 {
7909 "", // unused
7910 "https://www.example.org/direct_ssl",
7911 "ssl/www.example.org:443",
7912 true,
7913 },
7914 {
7915 "", // unused
7916 "https://[2001:1418:13:1::25]/direct",
7917 "ssl/[2001:1418:13:1::25]:443",
7918 true,
7919 },
7920 {
7921 "", // unused
7922 "http://host.with.alternate/direct",
7923 "ssl/host.with.alternate:443",
7924 true,
7925 },
[email protected]2d731a32010-04-29 01:04:067926 };
[email protected]2ff8b312010-04-26 22:20:547927
[email protected]d7599122014-05-24 03:37:237928 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067929
viettrungluue4a8b882014-10-16 06:17:387930 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077931 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027932 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067933 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437934 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067935
7936 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:287937 CaptureGroupNameTransportSocketPool* transport_conn_pool =
7938 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:137939 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:347940 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:447941 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7942 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:027943 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
7944 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:517945 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:067946
7947 EXPECT_EQ(ERR_IO_PENDING,
7948 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:187949 if (tests[i].ssl)
7950 EXPECT_EQ(tests[i].expected_group_name,
7951 ssl_conn_pool->last_group_name_received());
7952 else
7953 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:287954 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:067955 }
7956
[email protected]2d731a32010-04-29 01:04:067957}
7958
[email protected]23e482282013-06-14 16:08:027959TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:067960 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:237961 {
7962 "http_proxy",
7963 "http://www.example.org/http_proxy_normal",
7964 "www.example.org:80",
7965 false,
7966 },
[email protected]2d731a32010-04-29 01:04:067967
bncce36dca22015-04-21 22:11:237968 // SSL Tests
7969 {
7970 "http_proxy",
7971 "https://www.example.org/http_connect_ssl",
7972 "ssl/www.example.org:443",
7973 true,
7974 },
[email protected]af3490e2010-10-16 21:02:297975
bncce36dca22015-04-21 22:11:237976 {
7977 "http_proxy",
7978 "http://host.with.alternate/direct",
7979 "ssl/host.with.alternate:443",
7980 true,
7981 },
[email protected]45499252013-01-23 17:12:567982
bncce36dca22015-04-21 22:11:237983 {
7984 "http_proxy",
7985 "ftp://ftp.google.com/http_proxy_normal",
7986 "ftp/ftp.google.com:21",
7987 false,
7988 },
[email protected]2d731a32010-04-29 01:04:067989 };
7990
[email protected]d7599122014-05-24 03:37:237991 session_deps_.use_alternate_protocols = true;
[email protected]2d731a32010-04-29 01:04:067992
viettrungluue4a8b882014-10-16 06:17:387993 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:077994 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:027995 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:067996 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:437997 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:067998
7999 HttpNetworkSessionPeer peer(session);
8000
[email protected]e60e47a2010-07-14 03:37:188001 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138002 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348003 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138004 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348005 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028006
[email protected]831e4a32013-11-14 02:14:448007 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8008 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028009 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8010 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518011 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068012
8013 EXPECT_EQ(ERR_IO_PENDING,
8014 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188015 if (tests[i].ssl)
8016 EXPECT_EQ(tests[i].expected_group_name,
8017 ssl_conn_pool->last_group_name_received());
8018 else
8019 EXPECT_EQ(tests[i].expected_group_name,
8020 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068021 }
[email protected]2d731a32010-04-29 01:04:068022}
8023
[email protected]23e482282013-06-14 16:08:028024TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068025 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238026 {
8027 "socks4://socks_proxy:1080",
8028 "http://www.example.org/socks4_direct",
8029 "socks4/www.example.org:80",
8030 false,
8031 },
8032 {
8033 "socks5://socks_proxy:1080",
8034 "http://www.example.org/socks5_direct",
8035 "socks5/www.example.org:80",
8036 false,
8037 },
[email protected]2d731a32010-04-29 01:04:068038
bncce36dca22015-04-21 22:11:238039 // SSL Tests
8040 {
8041 "socks4://socks_proxy:1080",
8042 "https://www.example.org/socks4_ssl",
8043 "socks4/ssl/www.example.org:443",
8044 true,
8045 },
8046 {
8047 "socks5://socks_proxy:1080",
8048 "https://www.example.org/socks5_ssl",
8049 "socks5/ssl/www.example.org:443",
8050 true,
8051 },
[email protected]af3490e2010-10-16 21:02:298052
bncce36dca22015-04-21 22:11:238053 {
8054 "socks4://socks_proxy:1080",
8055 "http://host.with.alternate/direct",
8056 "socks4/ssl/host.with.alternate:443",
8057 true,
8058 },
[email protected]04e5be32009-06-26 20:00:318059 };
8060
[email protected]d7599122014-05-24 03:37:238061 session_deps_.use_alternate_protocols = true;
[email protected]2ff8b312010-04-26 22:20:548062
viettrungluue4a8b882014-10-16 06:17:388063 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078064 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028065 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068066 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438067 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028068
[email protected]2d731a32010-04-29 01:04:068069 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318070
[email protected]e60e47a2010-07-14 03:37:188071 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138072 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348073 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138074 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348075 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028076
[email protected]831e4a32013-11-14 02:14:448077 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8078 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028079 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8080 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518081 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318082
[email protected]262eec82013-03-19 21:01:368083 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508084 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318085
[email protected]2d731a32010-04-29 01:04:068086 EXPECT_EQ(ERR_IO_PENDING,
8087 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188088 if (tests[i].ssl)
8089 EXPECT_EQ(tests[i].expected_group_name,
8090 ssl_conn_pool->last_group_name_received());
8091 else
8092 EXPECT_EQ(tests[i].expected_group_name,
8093 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318094 }
8095}
8096
[email protected]23e482282013-06-14 16:08:028097TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278098 HttpRequestInfo request;
8099 request.method = "GET";
bncce36dca22015-04-21 22:11:238100 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278101
[email protected]bb88e1d32013-05-03 23:11:078102 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008103 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328104
[email protected]69719062010-01-05 20:09:218105 // This simulates failure resolving all hostnames; that means we will fail
8106 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078107 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328108
[email protected]3fe8d2f82013-10-17 08:56:078109 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258110 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418111 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258112
[email protected]49639fa2011-12-20 23:22:418113 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258114
[email protected]49639fa2011-12-20 23:22:418115 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258116 EXPECT_EQ(ERR_IO_PENDING, rv);
8117
[email protected]9172a982009-06-06 00:30:258118 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018119 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258120}
8121
[email protected]685af592010-05-11 19:31:248122// Base test to make sure that when the load flags for a request specify to
8123// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028124void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078125 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278126 // Issue a request, asking to bypass the cache(s).
8127 HttpRequestInfo request;
8128 request.method = "GET";
8129 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238130 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278131
[email protected]a2c2fb92009-07-18 07:31:048132 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078133 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328134
[email protected]3fe8d2f82013-10-17 08:56:078135 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8136 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288138
bncce36dca22015-04-21 22:11:238139 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288140 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298141 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078142 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238143 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8144 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478145 EXPECT_EQ(ERR_IO_PENDING, rv);
8146 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288147 EXPECT_EQ(OK, rv);
8148
8149 // Verify that it was added to host cache, by doing a subsequent async lookup
8150 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078151 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]b59ff372009-07-15 22:04:328154 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288155
bncce36dca22015-04-21 22:11:238156 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288157 // we can tell if the next lookup hit the cache, or the "network".
8158 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238159 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288160
8161 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8162 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068163 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398164 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078165 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288166
[email protected]3b9cca42009-06-16 01:08:288167 // Run the request.
[email protected]49639fa2011-12-20 23:22:418168 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288169 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418170 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288171
8172 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238173 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288174 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8175}
8176
[email protected]685af592010-05-11 19:31:248177// There are multiple load flags that should trigger the host cache bypass.
8178// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028179TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248180 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8181}
8182
[email protected]23e482282013-06-14 16:08:028183TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248184 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8185}
8186
[email protected]23e482282013-06-14 16:08:028187TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248188 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8189}
8190
[email protected]0877e3d2009-10-17 22:29:578191// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028192TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578193 HttpRequestInfo request;
8194 request.method = "GET";
8195 request.url = GURL("http://www.foo.com/");
8196 request.load_flags = 0;
8197
8198 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068199 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578200 };
[email protected]31a2bfe2010-02-09 08:03:398201 StaticSocketDataProvider data(NULL, 0,
8202 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078203 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078204 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578205
[email protected]49639fa2011-12-20 23:22:418206 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578207
8208 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418209 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578210
[email protected]49639fa2011-12-20 23:22:418211 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578212 EXPECT_EQ(ERR_IO_PENDING, rv);
8213
8214 rv = callback.WaitForResult();
8215 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8216}
8217
8218// Check that a connection closed after the start of the headers finishes ok.
[email protected]23e482282013-06-14 16:08:028219TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578220 HttpRequestInfo request;
8221 request.method = "GET";
8222 request.url = GURL("http://www.foo.com/");
8223 request.load_flags = 0;
8224
8225 MockRead data_reads[] = {
8226 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068227 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578228 };
8229
[email protected]31a2bfe2010-02-09 08:03:398230 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078231 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078232 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578233
[email protected]49639fa2011-12-20 23:22:418234 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578235
8236 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418237 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578238
[email protected]49639fa2011-12-20 23:22:418239 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578240 EXPECT_EQ(ERR_IO_PENDING, rv);
8241
8242 rv = callback.WaitForResult();
8243 EXPECT_EQ(OK, rv);
8244
8245 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508246 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578247
[email protected]90499482013-06-01 00:39:508248 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]0877e3d2009-10-17 22:29:578249 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8250
8251 std::string response_data;
8252 rv = ReadTransaction(trans.get(), &response_data);
8253 EXPECT_EQ(OK, rv);
8254 EXPECT_EQ("", response_data);
8255}
8256
8257// Make sure that a dropped connection while draining the body for auth
8258// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028259TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578260 HttpRequestInfo request;
8261 request.method = "GET";
bncce36dca22015-04-21 22:11:238262 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578263 request.load_flags = 0;
8264
8265 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238266 MockWrite(
8267 "GET / HTTP/1.1\r\n"
8268 "Host: www.example.org\r\n"
8269 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578270 };
8271
8272 MockRead data_reads1[] = {
8273 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8274 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8275 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8276 MockRead("Content-Length: 14\r\n\r\n"),
8277 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068278 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578279 };
8280
[email protected]31a2bfe2010-02-09 08:03:398281 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8282 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078283 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578284
8285 // After calling trans->RestartWithAuth(), this is the request we should
8286 // be issuing -- the final header line contains the credentials.
8287 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238288 MockWrite(
8289 "GET / HTTP/1.1\r\n"
8290 "Host: www.example.org\r\n"
8291 "Connection: keep-alive\r\n"
8292 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578293 };
8294
8295 // Lastly, the server responds with the actual content.
8296 MockRead data_reads2[] = {
8297 MockRead("HTTP/1.1 200 OK\r\n"),
8298 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8299 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068300 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578301 };
8302
[email protected]31a2bfe2010-02-09 08:03:398303 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8304 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078305 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:078306 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578307
[email protected]49639fa2011-12-20 23:22:418308 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578309
[email protected]262eec82013-03-19 21:01:368310 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508312
[email protected]49639fa2011-12-20 23:22:418313 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578314 EXPECT_EQ(ERR_IO_PENDING, rv);
8315
8316 rv = callback1.WaitForResult();
8317 EXPECT_EQ(OK, rv);
8318
8319 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508320 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048321 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578322
[email protected]49639fa2011-12-20 23:22:418323 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578324
[email protected]49639fa2011-12-20 23:22:418325 rv = trans->RestartWithAuth(
8326 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578327 EXPECT_EQ(ERR_IO_PENDING, rv);
8328
8329 rv = callback2.WaitForResult();
8330 EXPECT_EQ(OK, rv);
8331
8332 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508333 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578334 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8335 EXPECT_EQ(100, response->headers->GetContentLength());
8336}
8337
8338// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028339TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078340 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578341
8342 HttpRequestInfo request;
8343 request.method = "GET";
bncce36dca22015-04-21 22:11:238344 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578345 request.load_flags = 0;
8346
8347 MockRead proxy_reads[] = {
8348 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068349 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578350 };
8351
[email protected]31a2bfe2010-02-09 08:03:398352 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068353 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578354
[email protected]bb88e1d32013-05-03 23:11:078355 session_deps_.socket_factory->AddSocketDataProvider(&data);
8356 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578357
[email protected]49639fa2011-12-20 23:22:418358 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578359
[email protected]bb88e1d32013-05-03 23:11:078360 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578361
[email protected]3fe8d2f82013-10-17 08:56:078362 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578363 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578365
[email protected]49639fa2011-12-20 23:22:418366 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578367 EXPECT_EQ(ERR_IO_PENDING, rv);
8368
8369 rv = callback.WaitForResult();
8370 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8371}
8372
[email protected]23e482282013-06-14 16:08:028373TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468374 HttpRequestInfo request;
8375 request.method = "GET";
bncce36dca22015-04-21 22:11:238376 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468377 request.load_flags = 0;
8378
[email protected]3fe8d2f82013-10-17 08:56:078379 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278380 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418381 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278382
[email protected]e22e1362009-11-23 21:31:128383 MockRead data_reads[] = {
8384 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068385 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128386 };
[email protected]9492e4a2010-02-24 00:58:468387
8388 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078389 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468390
[email protected]49639fa2011-12-20 23:22:418391 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468392
[email protected]49639fa2011-12-20 23:22:418393 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468394 EXPECT_EQ(ERR_IO_PENDING, rv);
8395
8396 EXPECT_EQ(OK, callback.WaitForResult());
8397
8398 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508399 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468400
[email protected]90499482013-06-01 00:39:508401 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468402 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8403
8404 std::string response_data;
8405 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238406 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128407}
8408
[email protected]23e482282013-06-14 16:08:028409TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158410 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528411 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338412 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218413 UploadFileElementReader::ScopedOverridingContentLengthForTests
8414 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338415
[email protected]b2d26cfd2012-12-11 10:36:068416 ScopedVector<UploadElementReader> element_readers;
8417 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458418 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8419 temp_file_path, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078420 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278421
8422 HttpRequestInfo request;
8423 request.method = "POST";
bncce36dca22015-04-21 22:11:238424 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278425 request.upload_data_stream = &upload_data_stream;
8426 request.load_flags = 0;
8427
[email protected]3fe8d2f82013-10-17 08:56:078428 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278429 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418430 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338431
8432 MockRead data_reads[] = {
8433 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8434 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068435 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338436 };
[email protected]31a2bfe2010-02-09 08:03:398437 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078438 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338439
[email protected]49639fa2011-12-20 23:22:418440 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338441
[email protected]49639fa2011-12-20 23:22:418442 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338443 EXPECT_EQ(ERR_IO_PENDING, rv);
8444
8445 rv = callback.WaitForResult();
8446 EXPECT_EQ(OK, rv);
8447
8448 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508449 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338450
[email protected]90499482013-06-01 00:39:508451 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338452 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8453
8454 std::string response_data;
8455 rv = ReadTransaction(trans.get(), &response_data);
8456 EXPECT_EQ(OK, rv);
8457 EXPECT_EQ("hello world", response_data);
8458
[email protected]dd3aa792013-07-16 19:10:238459 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338460}
8461
[email protected]23e482282013-06-14 16:08:028462TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158463 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528464 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368465 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308466 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368467 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118468 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368469
[email protected]b2d26cfd2012-12-11 10:36:068470 ScopedVector<UploadElementReader> element_readers;
8471 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458472 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8473 temp_file, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078474 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278475
8476 HttpRequestInfo request;
8477 request.method = "POST";
bncce36dca22015-04-21 22:11:238478 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278479 request.upload_data_stream = &upload_data_stream;
8480 request.load_flags = 0;
8481
[email protected]999dd8c2013-11-12 06:45:548482 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078483 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278484 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418485 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368486
[email protected]999dd8c2013-11-12 06:45:548487 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078488 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368489
[email protected]49639fa2011-12-20 23:22:418490 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368491
[email protected]49639fa2011-12-20 23:22:418492 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368493 EXPECT_EQ(ERR_IO_PENDING, rv);
8494
8495 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548496 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368497
[email protected]dd3aa792013-07-16 19:10:238498 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368499}
8500
[email protected]02cad5d2013-10-02 08:14:038501TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8502 class FakeUploadElementReader : public UploadElementReader {
8503 public:
8504 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208505 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038506
8507 const CompletionCallback& callback() const { return callback_; }
8508
8509 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208510 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038511 callback_ = callback;
8512 return ERR_IO_PENDING;
8513 }
dchengb03027d2014-10-21 12:00:208514 uint64 GetContentLength() const override { return 0; }
8515 uint64 BytesRemaining() const override { return 0; }
8516 int Read(IOBuffer* buf,
8517 int buf_length,
8518 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038519 return ERR_FAILED;
8520 }
8521
8522 private:
8523 CompletionCallback callback_;
8524 };
8525
8526 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8527 ScopedVector<UploadElementReader> element_readers;
8528 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078529 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038530
8531 HttpRequestInfo request;
8532 request.method = "POST";
bncce36dca22015-04-21 22:11:238533 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038534 request.upload_data_stream = &upload_data_stream;
8535 request.load_flags = 0;
8536
[email protected]3fe8d2f82013-10-17 08:56:078537 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038538 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418539 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038540
8541 StaticSocketDataProvider data;
8542 session_deps_.socket_factory->AddSocketDataProvider(&data);
8543
8544 TestCompletionCallback callback;
8545 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8546 EXPECT_EQ(ERR_IO_PENDING, rv);
8547 base::MessageLoop::current()->RunUntilIdle();
8548
8549 // Transaction is pending on request body initialization.
8550 ASSERT_FALSE(fake_reader->callback().is_null());
8551
8552 // Return Init()'s result after the transaction gets destroyed.
8553 trans.reset();
8554 fake_reader->callback().Run(OK); // Should not crash.
8555}
8556
[email protected]aeefc9e82010-02-19 16:18:278557// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028558TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278559
8560 HttpRequestInfo request;
8561 request.method = "GET";
bncce36dca22015-04-21 22:11:238562 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278563 request.load_flags = 0;
8564
8565 // First transaction will request a resource and receive a Basic challenge
8566 // with realm="first_realm".
8567 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238568 MockWrite(
8569 "GET / HTTP/1.1\r\n"
8570 "Host: www.example.org\r\n"
8571 "Connection: keep-alive\r\n"
8572 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278573 };
8574 MockRead data_reads1[] = {
8575 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8576 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8577 "\r\n"),
8578 };
8579
8580 // After calling trans->RestartWithAuth(), provide an Authentication header
8581 // for first_realm. The server will reject and provide a challenge with
8582 // second_realm.
8583 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238584 MockWrite(
8585 "GET / HTTP/1.1\r\n"
8586 "Host: www.example.org\r\n"
8587 "Connection: keep-alive\r\n"
8588 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8589 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278590 };
8591 MockRead data_reads2[] = {
8592 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8593 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8594 "\r\n"),
8595 };
8596
8597 // This again fails, and goes back to first_realm. Make sure that the
8598 // entry is removed from cache.
8599 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238600 MockWrite(
8601 "GET / HTTP/1.1\r\n"
8602 "Host: www.example.org\r\n"
8603 "Connection: keep-alive\r\n"
8604 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8605 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278606 };
8607 MockRead data_reads3[] = {
8608 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8609 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8610 "\r\n"),
8611 };
8612
8613 // Try one last time (with the correct password) and get the resource.
8614 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238615 MockWrite(
8616 "GET / HTTP/1.1\r\n"
8617 "Host: www.example.org\r\n"
8618 "Connection: keep-alive\r\n"
8619 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8620 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278621 };
8622 MockRead data_reads4[] = {
8623 MockRead("HTTP/1.1 200 OK\r\n"
8624 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508625 "Content-Length: 5\r\n"
8626 "\r\n"
8627 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278628 };
8629
8630 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8631 data_writes1, arraysize(data_writes1));
8632 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8633 data_writes2, arraysize(data_writes2));
8634 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8635 data_writes3, arraysize(data_writes3));
8636 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8637 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078638 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8639 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8640 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8641 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278642
[email protected]49639fa2011-12-20 23:22:418643 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278644
[email protected]3fe8d2f82013-10-17 08:56:078645 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508646 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418647 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508648
[email protected]aeefc9e82010-02-19 16:18:278649 // Issue the first request with Authorize headers. There should be a
8650 // password prompt for first_realm waiting to be filled in after the
8651 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418652 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278653 EXPECT_EQ(ERR_IO_PENDING, rv);
8654 rv = callback1.WaitForResult();
8655 EXPECT_EQ(OK, rv);
8656 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508657 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048658 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8659 ASSERT_FALSE(challenge == NULL);
8660 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238661 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048662 EXPECT_EQ("first_realm", challenge->realm);
8663 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278664
8665 // Issue the second request with an incorrect password. There should be a
8666 // password prompt for second_realm waiting to be filled in after the
8667 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418668 TestCompletionCallback callback2;
8669 rv = trans->RestartWithAuth(
8670 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278671 EXPECT_EQ(ERR_IO_PENDING, rv);
8672 rv = callback2.WaitForResult();
8673 EXPECT_EQ(OK, rv);
8674 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508675 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048676 challenge = response->auth_challenge.get();
8677 ASSERT_FALSE(challenge == NULL);
8678 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238679 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048680 EXPECT_EQ("second_realm", challenge->realm);
8681 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278682
8683 // Issue the third request with another incorrect password. There should be
8684 // a password prompt for first_realm waiting to be filled in. If the password
8685 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8686 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418687 TestCompletionCallback callback3;
8688 rv = trans->RestartWithAuth(
8689 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278690 EXPECT_EQ(ERR_IO_PENDING, rv);
8691 rv = callback3.WaitForResult();
8692 EXPECT_EQ(OK, rv);
8693 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508694 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048695 challenge = response->auth_challenge.get();
8696 ASSERT_FALSE(challenge == NULL);
8697 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238698 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048699 EXPECT_EQ("first_realm", challenge->realm);
8700 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278701
8702 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418703 TestCompletionCallback callback4;
8704 rv = trans->RestartWithAuth(
8705 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278706 EXPECT_EQ(ERR_IO_PENDING, rv);
8707 rv = callback4.WaitForResult();
8708 EXPECT_EQ(OK, rv);
8709 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508710 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278711 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8712}
8713
[email protected]23e482282013-06-14 16:08:028714TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:238715 session_deps_.next_protos = SpdyNextProtos();
8716 session_deps_.use_alternate_protocols = true;
[email protected]a2cb8122010-03-10 17:22:428717
[email protected]8a0fc822013-06-27 20:52:438718 std::string alternate_protocol_http_header =
8719 GetAlternateProtocolHttpHeader();
8720
[email protected]564b4912010-03-09 16:30:428721 MockRead data_reads[] = {
8722 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:438723 MockRead(alternate_protocol_http_header.c_str()),
[email protected]564b4912010-03-09 16:30:428724 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068725 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:428726 };
8727
8728 HttpRequestInfo request;
8729 request.method = "GET";
bncce36dca22015-04-21 22:11:238730 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428731 request.load_flags = 0;
8732
8733 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8734
[email protected]bb88e1d32013-05-03 23:11:078735 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:428736
[email protected]49639fa2011-12-20 23:22:418737 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428738
[email protected]bb88e1d32013-05-03 23:11:078739 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:368740 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508741 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:428742
[email protected]49639fa2011-12-20 23:22:418743 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428744 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:538745
bncce36dca22015-04-21 22:11:238746 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:558747 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:538748 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:108749 AlternativeServiceVector alternative_service_vector =
8750 http_server_properties.GetAlternativeServices(http_host_port_pair);
8751 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:428752
8753 EXPECT_EQ(OK, callback.WaitForResult());
8754
8755 const HttpResponseInfo* response = trans->GetResponseInfo();
8756 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508757 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428758 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:538759 EXPECT_FALSE(response->was_fetched_via_spdy);
8760 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:428761
8762 std::string response_data;
8763 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8764 EXPECT_EQ("hello world", response_data);
8765
bncd9b132e2015-07-08 05:16:108766 alternative_service_vector =
8767 http_server_properties.GetAlternativeServices(http_host_port_pair);
8768 ASSERT_EQ(1u, alternative_service_vector.size());
8769 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc181b39a2015-03-17 21:36:478770 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
bncd9b132e2015-07-08 05:16:108771 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:428772}
8773
rch89c6e102015-03-18 18:56:528774TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
8775 session_deps_.next_protos = SpdyNextProtos();
8776 session_deps_.use_alternate_protocols = true;
8777
8778 MockRead data_reads[] = {
8779 MockRead("HTTP/1.1 200 OK\r\n"),
8780 MockRead("Alternate-Protocol: \r\n\r\n"),
8781 MockRead("hello world"),
8782 MockRead(SYNCHRONOUS, OK),
8783 };
8784
8785 HttpRequestInfo request;
8786 request.method = "GET";
bncce36dca22015-04-21 22:11:238787 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:528788 request.load_flags = 0;
8789
8790 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8791
8792 session_deps_.socket_factory->AddSocketDataProvider(&data);
8793
8794 TestCompletionCallback callback;
8795
8796 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8797
bncce36dca22015-04-21 22:11:238798 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:528799 HttpServerProperties& http_server_properties =
8800 *session->http_server_properties();
bnccacc0992015-03-20 20:22:228801 AlternativeService alternative_service(QUIC, "", 80);
8802 http_server_properties.SetAlternativeService(http_host_port_pair,
8803 alternative_service, 1.0);
8804
bncd9b132e2015-07-08 05:16:108805 AlternativeServiceVector alternative_service_vector =
8806 http_server_properties.GetAlternativeServices(http_host_port_pair);
8807 ASSERT_EQ(1u, alternative_service_vector.size());
8808 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:528809
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 EXPECT_EQ(OK, callback.WaitForResult());
8817
8818 const HttpResponseInfo* response = trans->GetResponseInfo();
8819 ASSERT_TRUE(response != NULL);
8820 ASSERT_TRUE(response->headers.get() != NULL);
8821 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8822 EXPECT_FALSE(response->was_fetched_via_spdy);
8823 EXPECT_FALSE(response->was_npn_negotiated);
8824
8825 std::string response_data;
8826 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8827 EXPECT_EQ("hello world", response_data);
8828
bncd9b132e2015-07-08 05:16:108829 alternative_service_vector =
8830 http_server_properties.GetAlternativeServices(http_host_port_pair);
8831 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:528832}
8833
[email protected]23e482282013-06-14 16:08:028834TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238835 MarkBrokenAlternateProtocolAndFallback) {
[email protected]d7599122014-05-24 03:37:238836 session_deps_.use_alternate_protocols = true;
[email protected]564b4912010-03-09 16:30:428837
8838 HttpRequestInfo request;
8839 request.method = "GET";
bncce36dca22015-04-21 22:11:238840 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:428841 request.load_flags = 0;
8842
[email protected]d973e99a2012-02-17 21:02:368843 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:428844 StaticSocketDataProvider first_data;
8845 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078846 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:428847
8848 MockRead data_reads[] = {
8849 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8850 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068851 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:428852 };
8853 StaticSocketDataProvider second_data(
8854 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078855 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:428856
[email protected]bb88e1d32013-05-03 23:11:078857 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:428858
[email protected]30d4c022013-07-18 22:58:168859 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538860 session->http_server_properties();
bnc8445b3002015-03-13 01:57:098861 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:118862 // Port must be < 1024, or the header will be ignored (since initial port was
8863 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:108864 const AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238865 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bncd9b132e2015-07-08 05:16:108866 666); // Port is ignored by MockConnect anyway.
bnccacc0992015-03-20 20:22:228867 http_server_properties->SetAlternativeService(host_port_pair,
8868 alternative_service, 1.0);
[email protected]564b4912010-03-09 16:30:428869
[email protected]262eec82013-03-19 21:01:368870 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508871 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418872 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:428873
[email protected]49639fa2011-12-20 23:22:418874 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:428875 EXPECT_EQ(ERR_IO_PENDING, rv);
8876 EXPECT_EQ(OK, callback.WaitForResult());
8877
8878 const HttpResponseInfo* response = trans->GetResponseInfo();
8879 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:508880 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:428881 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8882
8883 std::string response_data;
8884 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8885 EXPECT_EQ("hello world", response_data);
8886
bncd9b132e2015-07-08 05:16:108887 const AlternativeServiceVector alternative_service_vector =
8888 http_server_properties->GetAlternativeServices(host_port_pair);
8889 ASSERT_EQ(1u, alternative_service_vector.size());
8890 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
8891 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
8892 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:428893}
8894
[email protected]23e482282013-06-14 16:08:028895TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238896 AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:118897 // Ensure that we're not allowed to redirect traffic via an alternate
8898 // protocol to an unrestricted (port >= 1024) when the original traffic was
8899 // on a restricted port (port < 1024). Ensure that we can redirect in all
8900 // other cases.
[email protected]d7599122014-05-24 03:37:238901 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:118902
8903 HttpRequestInfo restricted_port_request;
8904 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238905 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:118906 restricted_port_request.load_flags = 0;
8907
[email protected]d973e99a2012-02-17 21:02:368908 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:118909 StaticSocketDataProvider first_data;
8910 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078911 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:118912
8913 MockRead data_reads[] = {
8914 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8915 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068916 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:118917 };
8918 StaticSocketDataProvider second_data(
8919 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078920 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:118921
[email protected]bb88e1d32013-05-03 23:11:078922 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:118923
[email protected]30d4c022013-07-18 22:58:168924 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:538925 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:118926 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:228927 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238928 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228929 kUnrestrictedAlternatePort);
8930 http_server_properties->SetAlternativeService(
8931 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:018932 1.0);
[email protected]3912662a32011-10-04 00:51:118933
[email protected]262eec82013-03-19 21:01:368934 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508935 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:418936 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:118937
[email protected]49639fa2011-12-20 23:22:418938 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:368939 &restricted_port_request,
8940 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:118941 EXPECT_EQ(ERR_IO_PENDING, rv);
8942 // Invalid change to unrestricted port should fail.
8943 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:198944}
[email protected]3912662a32011-10-04 00:51:118945
[email protected]23e482282013-06-14 16:08:028946TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:198947 AlternateProtocolPortRestrictedPermitted) {
8948 // Ensure that we're allowed to redirect traffic via an alternate
8949 // protocol to an unrestricted (port >= 1024) when the original traffic was
8950 // on a restricted port (port < 1024) if we set
8951 // enable_user_alternate_protocol_ports.
8952
[email protected]d7599122014-05-24 03:37:238953 session_deps_.use_alternate_protocols = true;
[email protected]bb88e1d32013-05-03 23:11:078954 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:198955
8956 HttpRequestInfo restricted_port_request;
8957 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:238958 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:198959 restricted_port_request.load_flags = 0;
8960
8961 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
8962 StaticSocketDataProvider first_data;
8963 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:078964 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:198965
8966 MockRead data_reads[] = {
8967 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
8968 MockRead("hello world"),
8969 MockRead(ASYNC, OK),
8970 };
8971 StaticSocketDataProvider second_data(
8972 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078973 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:198974
[email protected]bb88e1d32013-05-03 23:11:078975 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:198976
[email protected]30d4c022013-07-18 22:58:168977 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:198978 session->http_server_properties();
8979 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:228980 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:238981 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:228982 kUnrestrictedAlternatePort);
8983 http_server_properties->SetAlternativeService(
8984 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:018985 1.0);
[email protected]c54c6962013-02-01 04:53:198986
[email protected]262eec82013-03-19 21:01:368987 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508988 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:198989 TestCompletionCallback callback;
8990
8991 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:368992 &restricted_port_request,
8993 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:198994 // Change to unrestricted port should succeed.
8995 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:118996}
8997
[email protected]23e482282013-06-14 16:08:028998TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:238999 AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:119000 // Ensure that we're not allowed to redirect traffic via an alternate
9001 // protocol to an unrestricted (port >= 1024) when the original traffic was
9002 // on a restricted port (port < 1024). Ensure that we can redirect in all
9003 // other cases.
[email protected]d7599122014-05-24 03:37:239004 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119005
9006 HttpRequestInfo restricted_port_request;
9007 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239008 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119009 restricted_port_request.load_flags = 0;
9010
[email protected]d973e99a2012-02-17 21:02:369011 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119012 StaticSocketDataProvider first_data;
9013 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079014 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119015
9016 MockRead data_reads[] = {
9017 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9018 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069019 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119020 };
9021 StaticSocketDataProvider second_data(
9022 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079023 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119024
[email protected]bb88e1d32013-05-03 23:11:079025 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119026
[email protected]30d4c022013-07-18 22:58:169027 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539028 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119029 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229030 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239031 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229032 kRestrictedAlternatePort);
9033 http_server_properties->SetAlternativeService(
9034 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019035 1.0);
[email protected]3912662a32011-10-04 00:51:119036
[email protected]262eec82013-03-19 21:01:369037 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509038 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419039 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119040
[email protected]49639fa2011-12-20 23:22:419041 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369042 &restricted_port_request,
9043 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119044 EXPECT_EQ(ERR_IO_PENDING, rv);
9045 // Valid change to restricted port should pass.
9046 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119047}
9048
[email protected]23e482282013-06-14 16:08:029049TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239050 AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:119051 // Ensure that we're not allowed to redirect traffic via an alternate
9052 // protocol to an unrestricted (port >= 1024) when the original traffic was
9053 // on a restricted port (port < 1024). Ensure that we can redirect in all
9054 // other cases.
[email protected]d7599122014-05-24 03:37:239055 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119056
9057 HttpRequestInfo unrestricted_port_request;
9058 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239059 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119060 unrestricted_port_request.load_flags = 0;
9061
[email protected]d973e99a2012-02-17 21:02:369062 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119063 StaticSocketDataProvider first_data;
9064 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079065 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119066
9067 MockRead data_reads[] = {
9068 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9069 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069070 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119071 };
9072 StaticSocketDataProvider second_data(
9073 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079074 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119075
[email protected]bb88e1d32013-05-03 23:11:079076 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119077
[email protected]30d4c022013-07-18 22:58:169078 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539079 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119080 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229081 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239082 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229083 kRestrictedAlternatePort);
9084 http_server_properties->SetAlternativeService(
9085 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019086 1.0);
[email protected]3912662a32011-10-04 00:51:119087
[email protected]262eec82013-03-19 21:01:369088 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509089 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419090 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119091
[email protected]49639fa2011-12-20 23:22:419092 int rv = trans->Start(
9093 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119094 EXPECT_EQ(ERR_IO_PENDING, rv);
9095 // Valid change to restricted port should pass.
9096 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119097}
9098
[email protected]23e482282013-06-14 16:08:029099TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239100 AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:119101 // Ensure that we're not allowed to redirect traffic via an alternate
9102 // protocol to an unrestricted (port >= 1024) when the original traffic was
9103 // on a restricted port (port < 1024). Ensure that we can redirect in all
9104 // other cases.
[email protected]d7599122014-05-24 03:37:239105 session_deps_.use_alternate_protocols = true;
[email protected]3912662a32011-10-04 00:51:119106
9107 HttpRequestInfo unrestricted_port_request;
9108 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239109 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119110 unrestricted_port_request.load_flags = 0;
9111
[email protected]d973e99a2012-02-17 21:02:369112 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119113 StaticSocketDataProvider first_data;
9114 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079115 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119116
9117 MockRead data_reads[] = {
9118 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9119 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069120 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119121 };
9122 StaticSocketDataProvider second_data(
9123 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079124 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119125
[email protected]bb88e1d32013-05-03 23:11:079126 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119127
[email protected]30d4c022013-07-18 22:58:169128 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539129 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119130 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229131 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239132 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229133 kUnrestrictedAlternatePort);
9134 http_server_properties->SetAlternativeService(
9135 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc1102b552015-01-30 20:11:019136 1.0);
[email protected]3912662a32011-10-04 00:51:119137
[email protected]262eec82013-03-19 21:01:369138 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509139 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419140 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119141
[email protected]49639fa2011-12-20 23:22:419142 int rv = trans->Start(
9143 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119144 EXPECT_EQ(ERR_IO_PENDING, rv);
9145 // Valid change to an unrestricted port should pass.
9146 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119147}
9148
[email protected]d7599122014-05-24 03:37:239149TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:029150 // Ensure that we're not allowed to redirect traffic via an alternate
9151 // protocol to an unsafe port, and that we resume the second
9152 // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239153 session_deps_.use_alternate_protocols = true;
[email protected]eb6234e2012-01-19 01:50:029154
9155 HttpRequestInfo request;
9156 request.method = "GET";
bncce36dca22015-04-21 22:11:239157 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029158 request.load_flags = 0;
9159
9160 // The alternate protocol request will error out before we attempt to connect,
9161 // so only the standard HTTP request will try to connect.
9162 MockRead data_reads[] = {
9163 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9164 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069165 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029166 };
9167 StaticSocketDataProvider data(
9168 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079169 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029170
[email protected]bb88e1d32013-05-03 23:11:079171 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029172
[email protected]30d4c022013-07-18 22:58:169173 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029174 session->http_server_properties();
9175 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229176 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239177 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229178 kUnsafePort);
9179 http_server_properties->SetAlternativeService(
9180 HostPortPair::FromURL(request.url), alternative_service, 1.0);
[email protected]eb6234e2012-01-19 01:50:029181
[email protected]262eec82013-03-19 21:01:369182 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509183 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029184 TestCompletionCallback callback;
9185
9186 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9187 EXPECT_EQ(ERR_IO_PENDING, rv);
9188 // The HTTP request should succeed.
9189 EXPECT_EQ(OK, callback.WaitForResult());
9190
9191 // Disable alternate protocol before the asserts.
[email protected]d7599122014-05-24 03:37:239192 // HttpStreamFactory::set_use_alternate_protocols(false);
[email protected]eb6234e2012-01-19 01:50:029193
9194 const HttpResponseInfo* response = trans->GetResponseInfo();
9195 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509196 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029197 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9198
9199 std::string response_data;
9200 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9201 EXPECT_EQ("hello world", response_data);
9202}
9203
[email protected]23e482282013-06-14 16:08:029204TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239205 session_deps_.use_alternate_protocols = true;
9206 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549207
9208 HttpRequestInfo request;
9209 request.method = "GET";
bncce36dca22015-04-21 22:11:239210 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549211 request.load_flags = 0;
9212
[email protected]8a0fc822013-06-27 20:52:439213 std::string alternate_protocol_http_header =
9214 GetAlternateProtocolHttpHeader();
9215
[email protected]2ff8b312010-04-26 22:20:549216 MockRead data_reads[] = {
9217 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439218 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549219 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179220 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9221 MockRead(ASYNC, OK)
[email protected]2ff8b312010-04-26 22:20:549222 };
9223
9224 StaticSocketDataProvider first_transaction(
9225 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079226 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549227
[email protected]8ddf8322012-02-23 18:08:069228 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029229 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239230 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9231 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079232 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549233
[email protected]cdf8f7e72013-05-23 10:56:469234 scoped_ptr<SpdyFrame> req(
9235 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139236 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549237
[email protected]23e482282013-06-14 16:08:029238 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9239 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549240 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139241 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549242 };
9243
rch8e6c6c42015-05-01 14:05:139244 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9245 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079246 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549247
[email protected]d973e99a2012-02-17 21:02:369248 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559249 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9250 NULL, 0, NULL, 0);
9251 hanging_non_alternate_protocol_socket.set_connect_data(
9252 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079253 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559254 &hanging_non_alternate_protocol_socket);
9255
[email protected]49639fa2011-12-20 23:22:419256 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549257
[email protected]bb88e1d32013-05-03 23:11:079258 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369259 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509260 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549261
[email protected]49639fa2011-12-20 23:22:419262 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549263 EXPECT_EQ(ERR_IO_PENDING, rv);
9264 EXPECT_EQ(OK, callback.WaitForResult());
9265
9266 const HttpResponseInfo* response = trans->GetResponseInfo();
9267 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509268 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549269 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9270
9271 std::string response_data;
9272 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9273 EXPECT_EQ("hello world", response_data);
9274
[email protected]90499482013-06-01 00:39:509275 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549276
[email protected]49639fa2011-12-20 23:22:419277 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549278 EXPECT_EQ(ERR_IO_PENDING, rv);
9279 EXPECT_EQ(OK, callback.WaitForResult());
9280
9281 response = trans->GetResponseInfo();
9282 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509283 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549284 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539285 EXPECT_TRUE(response->was_fetched_via_spdy);
9286 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549287
9288 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9289 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549290}
9291
[email protected]23e482282013-06-14 16:08:029292TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]d7599122014-05-24 03:37:239293 session_deps_.use_alternate_protocols = true;
9294 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559295
9296 HttpRequestInfo request;
9297 request.method = "GET";
bncce36dca22015-04-21 22:11:239298 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559299 request.load_flags = 0;
9300
[email protected]8a0fc822013-06-27 20:52:439301 std::string alternate_protocol_http_header =
9302 GetAlternateProtocolHttpHeader();
9303
[email protected]2d6728692011-03-12 01:39:559304 MockRead data_reads[] = {
9305 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439306 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559307 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179308 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069309 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559310 };
9311
9312 StaticSocketDataProvider first_transaction(
9313 data_reads, arraysize(data_reads), NULL, 0);
9314 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079315 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559316
[email protected]d973e99a2012-02-17 21:02:369317 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559318 StaticSocketDataProvider hanging_socket(
9319 NULL, 0, NULL, 0);
9320 hanging_socket.set_connect_data(never_finishing_connect);
9321 // Socket 2 and 3 are the hanging Alternate-Protocol and
9322 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079323 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9324 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559325
[email protected]8ddf8322012-02-23 18:08:069326 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029327 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239328 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9329 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079330 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559331
[email protected]cdf8f7e72013-05-23 10:56:469332 scoped_ptr<SpdyFrame> req1(
9333 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9334 scoped_ptr<SpdyFrame> req2(
9335 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559336 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139337 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559338 };
[email protected]23e482282013-06-14 16:08:029339 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9340 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9341 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9342 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559343 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139344 CreateMockRead(*resp1, 2),
9345 CreateMockRead(*data1, 3),
9346 CreateMockRead(*resp2, 4),
9347 CreateMockRead(*data2, 5),
9348 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559349 };
9350
rch8e6c6c42015-05-01 14:05:139351 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9352 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559353 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079354 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559355
9356 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079357 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559358
[email protected]bb88e1d32013-05-03 23:11:079359 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419360 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509361 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559362
[email protected]49639fa2011-12-20 23:22:419363 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559364 EXPECT_EQ(ERR_IO_PENDING, rv);
9365 EXPECT_EQ(OK, callback1.WaitForResult());
9366
9367 const HttpResponseInfo* response = trans1.GetResponseInfo();
9368 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509369 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559370 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9371
9372 std::string response_data;
9373 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9374 EXPECT_EQ("hello world", response_data);
9375
[email protected]49639fa2011-12-20 23:22:419376 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509377 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419378 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559379 EXPECT_EQ(ERR_IO_PENDING, rv);
9380
[email protected]49639fa2011-12-20 23:22:419381 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509382 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419383 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559384 EXPECT_EQ(ERR_IO_PENDING, rv);
9385
9386 EXPECT_EQ(OK, callback2.WaitForResult());
9387 EXPECT_EQ(OK, callback3.WaitForResult());
9388
9389 response = trans2.GetResponseInfo();
9390 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509391 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559392 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9393 EXPECT_TRUE(response->was_fetched_via_spdy);
9394 EXPECT_TRUE(response->was_npn_negotiated);
9395 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9396 EXPECT_EQ("hello!", response_data);
9397
9398 response = trans3.GetResponseInfo();
9399 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509400 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559401 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9402 EXPECT_TRUE(response->was_fetched_via_spdy);
9403 EXPECT_TRUE(response->was_npn_negotiated);
9404 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9405 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559406}
9407
[email protected]23e482282013-06-14 16:08:029408TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239409 session_deps_.use_alternate_protocols = true;
9410 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559411
9412 HttpRequestInfo request;
9413 request.method = "GET";
bncce36dca22015-04-21 22:11:239414 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559415 request.load_flags = 0;
9416
[email protected]8a0fc822013-06-27 20:52:439417 std::string alternate_protocol_http_header =
9418 GetAlternateProtocolHttpHeader();
9419
[email protected]2d6728692011-03-12 01:39:559420 MockRead data_reads[] = {
9421 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439422 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2d6728692011-03-12 01:39:559423 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179424 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069425 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559426 };
9427
9428 StaticSocketDataProvider first_transaction(
9429 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079430 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559431
[email protected]8ddf8322012-02-23 18:08:069432 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029433 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079434 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559435
[email protected]d973e99a2012-02-17 21:02:369436 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559437 StaticSocketDataProvider hanging_alternate_protocol_socket(
9438 NULL, 0, NULL, 0);
9439 hanging_alternate_protocol_socket.set_connect_data(
9440 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079441 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559442 &hanging_alternate_protocol_socket);
9443
9444 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079445 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559446
[email protected]49639fa2011-12-20 23:22:419447 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559448
[email protected]bb88e1d32013-05-03 23:11:079449 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369450 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509451 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559452
[email protected]49639fa2011-12-20 23:22:419453 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559454 EXPECT_EQ(ERR_IO_PENDING, rv);
9455 EXPECT_EQ(OK, callback.WaitForResult());
9456
9457 const HttpResponseInfo* response = trans->GetResponseInfo();
9458 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509459 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559460 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9461
9462 std::string response_data;
9463 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9464 EXPECT_EQ("hello world", response_data);
9465
[email protected]90499482013-06-01 00:39:509466 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559467
[email protected]49639fa2011-12-20 23:22:419468 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559469 EXPECT_EQ(ERR_IO_PENDING, rv);
9470 EXPECT_EQ(OK, callback.WaitForResult());
9471
9472 response = trans->GetResponseInfo();
9473 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509474 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559475 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9476 EXPECT_FALSE(response->was_fetched_via_spdy);
9477 EXPECT_FALSE(response->was_npn_negotiated);
9478
9479 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9480 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559481}
9482
[email protected]631f1322010-04-30 17:59:119483class CapturingProxyResolver : public ProxyResolver {
9484 public:
sammce90c9212015-05-27 23:43:359485 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:209486 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119487
dchengb03027d2014-10-21 12:00:209488 int GetProxyForURL(const GURL& url,
9489 ProxyInfo* results,
9490 const CompletionCallback& callback,
9491 RequestHandle* request,
9492 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409493 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9494 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429495 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119496 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429497 return OK;
[email protected]631f1322010-04-30 17:59:119498 }
9499
dchengb03027d2014-10-21 12:00:209500 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119501
dchengb03027d2014-10-21 12:00:209502 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179503 NOTREACHED();
9504 return LOAD_STATE_IDLE;
9505 }
9506
[email protected]24476402010-07-20 20:55:179507 const std::vector<GURL>& resolved() const { return resolved_; }
9508
9509 private:
[email protected]631f1322010-04-30 17:59:119510 std::vector<GURL> resolved_;
9511
9512 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9513};
9514
sammce64b2362015-04-29 03:50:239515class CapturingProxyResolverFactory : public ProxyResolverFactory {
9516 public:
9517 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
9518 : ProxyResolverFactory(false), resolver_(resolver) {}
9519
9520 int CreateProxyResolver(
9521 const scoped_refptr<ProxyResolverScriptData>& pac_script,
9522 scoped_ptr<ProxyResolver>* resolver,
9523 const net::CompletionCallback& callback,
9524 scoped_ptr<Request>* request) override {
9525 resolver->reset(new ForwardingProxyResolver(resolver_));
9526 return OK;
9527 }
9528
9529 private:
9530 ProxyResolver* resolver_;
9531};
9532
[email protected]23e482282013-06-14 16:08:029533TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239534 UseAlternateProtocolForTunneledNpnSpdy) {
[email protected]d7599122014-05-24 03:37:239535 session_deps_.use_alternate_protocols = true;
9536 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119537
9538 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429539 proxy_config.set_auto_detect(true);
9540 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119541
sammc5dd160c2015-04-02 02:43:139542 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:079543 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:139544 new ProxyConfigServiceFixed(proxy_config),
9545 make_scoped_ptr(
sammce64b2362015-04-29 03:50:239546 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:389547 NULL));
vishal.b62985ca92015-04-17 08:45:519548 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079549 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119550
9551 HttpRequestInfo request;
9552 request.method = "GET";
bncce36dca22015-04-21 22:11:239553 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:119554 request.load_flags = 0;
9555
[email protected]8a0fc822013-06-27 20:52:439556 std::string alternate_protocol_http_header =
9557 GetAlternateProtocolHttpHeader();
9558
[email protected]631f1322010-04-30 17:59:119559 MockRead data_reads[] = {
9560 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439561 MockRead(alternate_protocol_http_header.c_str()),
[email protected]631f1322010-04-30 17:59:119562 MockRead("hello world"),
[email protected]7a5378b2012-11-04 03:25:179563 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]8ddf8322012-02-23 18:08:069564 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119565 };
9566
9567 StaticSocketDataProvider first_transaction(
9568 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079569 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119570
[email protected]8ddf8322012-02-23 18:08:069571 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029572 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239573 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9574 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079575 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119576
[email protected]cdf8f7e72013-05-23 10:56:469577 scoped_ptr<SpdyFrame> req(
9578 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119579 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139580 MockWrite(ASYNC, 0,
9581 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9582 "Host: www.example.org\r\n"
9583 "Proxy-Connection: keep-alive\r\n\r\n"),
9584 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:119585 };
9586
[email protected]d911f1b2010-05-05 22:39:429587 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
9588
[email protected]23e482282013-06-14 16:08:029589 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9590 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:119591 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139592 MockRead(ASYNC, 1, kCONNECTResponse),
9593 CreateMockRead(*resp.get(), 3),
9594 CreateMockRead(*data.get(), 4),
9595 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:119596 };
9597
rch8e6c6c42015-05-01 14:05:139598 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9599 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079600 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:119601
[email protected]d973e99a2012-02-17 21:02:369602 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559603 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9604 NULL, 0, NULL, 0);
9605 hanging_non_alternate_protocol_socket.set_connect_data(
9606 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079607 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559608 &hanging_non_alternate_protocol_socket);
9609
[email protected]49639fa2011-12-20 23:22:419610 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:119611
[email protected]bb88e1d32013-05-03 23:11:079612 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369613 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509614 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119615
[email protected]49639fa2011-12-20 23:22:419616 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119617 EXPECT_EQ(ERR_IO_PENDING, rv);
9618 EXPECT_EQ(OK, callback.WaitForResult());
9619
9620 const HttpResponseInfo* response = trans->GetResponseInfo();
9621 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509622 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119623 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539624 EXPECT_FALSE(response->was_fetched_via_spdy);
9625 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119626
9627 std::string response_data;
9628 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9629 EXPECT_EQ("hello world", response_data);
9630
[email protected]90499482013-06-01 00:39:509631 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:119632
[email protected]49639fa2011-12-20 23:22:419633 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:119634 EXPECT_EQ(ERR_IO_PENDING, rv);
9635 EXPECT_EQ(OK, callback.WaitForResult());
9636
9637 response = trans->GetResponseInfo();
9638 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509639 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:119640 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539641 EXPECT_TRUE(response->was_fetched_via_spdy);
9642 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:119643
9644 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9645 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:139646 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:239647 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:139648 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:239649 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:139650 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:119651
[email protected]029c83b62013-01-24 05:28:209652 LoadTimingInfo load_timing_info;
9653 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9654 TestLoadTimingNotReusedWithPac(load_timing_info,
9655 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:119656}
[email protected]631f1322010-04-30 17:59:119657
[email protected]23e482282013-06-14 16:08:029658TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:549659 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
[email protected]d7599122014-05-24 03:37:239660 session_deps_.use_alternate_protocols = true;
9661 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549662
9663 HttpRequestInfo request;
9664 request.method = "GET";
bncce36dca22015-04-21 22:11:239665 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549666 request.load_flags = 0;
9667
[email protected]8a0fc822013-06-27 20:52:439668 std::string alternate_protocol_http_header =
9669 GetAlternateProtocolHttpHeader();
9670
[email protected]2ff8b312010-04-26 22:20:549671 MockRead data_reads[] = {
9672 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:439673 MockRead(alternate_protocol_http_header.c_str()),
[email protected]2ff8b312010-04-26 22:20:549674 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069675 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:549676 };
9677
9678 StaticSocketDataProvider first_transaction(
9679 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079680 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549681
[email protected]8ddf8322012-02-23 18:08:069682 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029683 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239684 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9685 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079686 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549687
[email protected]cdf8f7e72013-05-23 10:56:469688 scoped_ptr<SpdyFrame> req(
9689 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139690 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549691
[email protected]23e482282013-06-14 16:08:029692 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9693 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549694 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139695 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549696 };
9697
rch8e6c6c42015-05-01 14:05:139698 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9699 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079700 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549701
[email protected]83039bb2011-12-09 18:43:559702 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549703
[email protected]bb88e1d32013-05-03 23:11:079704 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:549705
[email protected]262eec82013-03-19 21:01:369706 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509707 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549708
[email protected]49639fa2011-12-20 23:22:419709 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549710 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419711 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549712
9713 const HttpResponseInfo* response = trans->GetResponseInfo();
9714 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509715 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549716 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9717
9718 std::string response_data;
9719 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9720 EXPECT_EQ("hello world", response_data);
9721
9722 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:239723 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:409724 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:539725 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:279726 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:269727 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:389728
[email protected]90499482013-06-01 00:39:509729 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549730
[email protected]49639fa2011-12-20 23:22:419731 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549732 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419733 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:549734
9735 response = trans->GetResponseInfo();
9736 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509737 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549738 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539739 EXPECT_TRUE(response->was_fetched_via_spdy);
9740 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549741
9742 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9743 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:429744}
9745
[email protected]044de0642010-06-17 10:42:159746// GenerateAuthToken is a mighty big test.
9747// It tests all permutation of GenerateAuthToken behavior:
9748// - Synchronous and Asynchronous completion.
9749// - OK or error on completion.
9750// - Direct connection, non-authenticating proxy, and authenticating proxy.
9751// - HTTP or HTTPS backend (to include proxy tunneling).
9752// - Non-authenticating and authenticating backend.
9753//
[email protected]fe3b7dc2012-02-03 19:52:099754// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:159755// problems generating an auth token for an authenticating proxy, we don't
9756// need to test all permutations of the backend server).
9757//
9758// The test proceeds by going over each of the configuration cases, and
9759// potentially running up to three rounds in each of the tests. The TestConfig
9760// specifies both the configuration for the test as well as the expectations
9761// for the results.
[email protected]23e482282013-06-14 16:08:029762TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:509763 static const char kServer[] = "http://www.example.com";
9764 static const char kSecureServer[] = "https://www.example.com";
9765 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:159766 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
9767
9768 enum AuthTiming {
9769 AUTH_NONE,
9770 AUTH_SYNC,
9771 AUTH_ASYNC,
9772 };
9773
9774 const MockWrite kGet(
9775 "GET / HTTP/1.1\r\n"
9776 "Host: www.example.com\r\n"
9777 "Connection: keep-alive\r\n\r\n");
9778 const MockWrite kGetProxy(
9779 "GET http://www.example.com/ HTTP/1.1\r\n"
9780 "Host: www.example.com\r\n"
9781 "Proxy-Connection: keep-alive\r\n\r\n");
9782 const MockWrite kGetAuth(
9783 "GET / HTTP/1.1\r\n"
9784 "Host: www.example.com\r\n"
9785 "Connection: keep-alive\r\n"
9786 "Authorization: auth_token\r\n\r\n");
9787 const MockWrite kGetProxyAuth(
9788 "GET http://www.example.com/ HTTP/1.1\r\n"
9789 "Host: www.example.com\r\n"
9790 "Proxy-Connection: keep-alive\r\n"
9791 "Proxy-Authorization: auth_token\r\n\r\n");
9792 const MockWrite kGetAuthThroughProxy(
9793 "GET http://www.example.com/ HTTP/1.1\r\n"
9794 "Host: www.example.com\r\n"
9795 "Proxy-Connection: keep-alive\r\n"
9796 "Authorization: auth_token\r\n\r\n");
9797 const MockWrite kGetAuthWithProxyAuth(
9798 "GET http://www.example.com/ HTTP/1.1\r\n"
9799 "Host: www.example.com\r\n"
9800 "Proxy-Connection: keep-alive\r\n"
9801 "Proxy-Authorization: auth_token\r\n"
9802 "Authorization: auth_token\r\n\r\n");
9803 const MockWrite kConnect(
9804 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9805 "Host: www.example.com\r\n"
9806 "Proxy-Connection: keep-alive\r\n\r\n");
9807 const MockWrite kConnectProxyAuth(
9808 "CONNECT www.example.com:443 HTTP/1.1\r\n"
9809 "Host: www.example.com\r\n"
9810 "Proxy-Connection: keep-alive\r\n"
9811 "Proxy-Authorization: auth_token\r\n\r\n");
9812
9813 const MockRead kSuccess(
9814 "HTTP/1.1 200 OK\r\n"
9815 "Content-Type: text/html; charset=iso-8859-1\r\n"
9816 "Content-Length: 3\r\n\r\n"
9817 "Yes");
9818 const MockRead kFailure(
9819 "Should not be called.");
9820 const MockRead kServerChallenge(
9821 "HTTP/1.1 401 Unauthorized\r\n"
9822 "WWW-Authenticate: Mock realm=server\r\n"
9823 "Content-Type: text/html; charset=iso-8859-1\r\n"
9824 "Content-Length: 14\r\n\r\n"
9825 "Unauthorized\r\n");
9826 const MockRead kProxyChallenge(
9827 "HTTP/1.1 407 Unauthorized\r\n"
9828 "Proxy-Authenticate: Mock realm=proxy\r\n"
9829 "Proxy-Connection: close\r\n"
9830 "Content-Type: text/html; charset=iso-8859-1\r\n"
9831 "Content-Length: 14\r\n\r\n"
9832 "Unauthorized\r\n");
9833 const MockRead kProxyConnected(
9834 "HTTP/1.1 200 Connection Established\r\n\r\n");
9835
9836 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
9837 // no constructors, but the C++ compiler on Windows warns about
9838 // unspecified data in compound literals. So, moved to using constructors,
9839 // and TestRound's created with the default constructor should not be used.
9840 struct TestRound {
9841 TestRound()
9842 : expected_rv(ERR_UNEXPECTED),
9843 extra_write(NULL),
9844 extra_read(NULL) {
9845 }
9846 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9847 int expected_rv_arg)
9848 : write(write_arg),
9849 read(read_arg),
9850 expected_rv(expected_rv_arg),
9851 extra_write(NULL),
9852 extra_read(NULL) {
9853 }
9854 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
9855 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:019856 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:159857 : write(write_arg),
9858 read(read_arg),
9859 expected_rv(expected_rv_arg),
9860 extra_write(extra_write_arg),
9861 extra_read(extra_read_arg) {
9862 }
9863 MockWrite write;
9864 MockRead read;
9865 int expected_rv;
9866 const MockWrite* extra_write;
9867 const MockRead* extra_read;
9868 };
9869
9870 static const int kNoSSL = 500;
9871
9872 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:519873 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:159874 AuthTiming proxy_auth_timing;
9875 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:519876 const char* const server_url;
[email protected]044de0642010-06-17 10:42:159877 AuthTiming server_auth_timing;
9878 int server_auth_rv;
9879 int num_auth_rounds;
9880 int first_ssl_round;
9881 TestRound rounds[3];
9882 } test_configs[] = {
9883 // Non-authenticating HTTP server with a direct connection.
9884 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9885 { TestRound(kGet, kSuccess, OK)}},
9886 // Authenticating HTTP server with a direct connection.
9887 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9888 { TestRound(kGet, kServerChallenge, OK),
9889 TestRound(kGetAuth, kSuccess, OK)}},
9890 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9891 { TestRound(kGet, kServerChallenge, OK),
9892 TestRound(kGetAuth, kFailure, kAuthErr)}},
9893 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9894 { TestRound(kGet, kServerChallenge, OK),
9895 TestRound(kGetAuth, kSuccess, OK)}},
9896 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9897 { TestRound(kGet, kServerChallenge, OK),
9898 TestRound(kGetAuth, kFailure, kAuthErr)}},
9899 // Non-authenticating HTTP server through a non-authenticating proxy.
9900 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
9901 { TestRound(kGetProxy, kSuccess, OK)}},
9902 // Authenticating HTTP server through a non-authenticating proxy.
9903 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
9904 { TestRound(kGetProxy, kServerChallenge, OK),
9905 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9906 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
9907 { TestRound(kGetProxy, kServerChallenge, OK),
9908 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9909 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
9910 { TestRound(kGetProxy, kServerChallenge, OK),
9911 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
9912 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
9913 { TestRound(kGetProxy, kServerChallenge, OK),
9914 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
9915 // Non-authenticating HTTP server through an authenticating proxy.
9916 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9917 { TestRound(kGetProxy, kProxyChallenge, OK),
9918 TestRound(kGetProxyAuth, kSuccess, OK)}},
9919 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9920 { TestRound(kGetProxy, kProxyChallenge, OK),
9921 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9922 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
9923 { TestRound(kGetProxy, kProxyChallenge, OK),
9924 TestRound(kGetProxyAuth, kSuccess, OK)}},
9925 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
9926 { TestRound(kGetProxy, kProxyChallenge, OK),
9927 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
9928 // Authenticating HTTP server through an authenticating proxy.
9929 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9930 { TestRound(kGetProxy, kProxyChallenge, OK),
9931 TestRound(kGetProxyAuth, kServerChallenge, OK),
9932 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9933 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9934 { TestRound(kGetProxy, kProxyChallenge, OK),
9935 TestRound(kGetProxyAuth, kServerChallenge, OK),
9936 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9937 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
9938 { TestRound(kGetProxy, kProxyChallenge, OK),
9939 TestRound(kGetProxyAuth, kServerChallenge, OK),
9940 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9941 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
9942 { TestRound(kGetProxy, kProxyChallenge, OK),
9943 TestRound(kGetProxyAuth, kServerChallenge, OK),
9944 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9945 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9946 { TestRound(kGetProxy, kProxyChallenge, OK),
9947 TestRound(kGetProxyAuth, kServerChallenge, OK),
9948 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9949 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9950 { TestRound(kGetProxy, kProxyChallenge, OK),
9951 TestRound(kGetProxyAuth, kServerChallenge, OK),
9952 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9953 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
9954 { TestRound(kGetProxy, kProxyChallenge, OK),
9955 TestRound(kGetProxyAuth, kServerChallenge, OK),
9956 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
9957 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
9958 { TestRound(kGetProxy, kProxyChallenge, OK),
9959 TestRound(kGetProxyAuth, kServerChallenge, OK),
9960 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
9961 // Non-authenticating HTTPS server with a direct connection.
9962 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9963 { TestRound(kGet, kSuccess, OK)}},
9964 // Authenticating HTTPS server with a direct connection.
9965 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9966 { TestRound(kGet, kServerChallenge, OK),
9967 TestRound(kGetAuth, kSuccess, OK)}},
9968 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9969 { TestRound(kGet, kServerChallenge, OK),
9970 TestRound(kGetAuth, kFailure, kAuthErr)}},
9971 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9972 { TestRound(kGet, kServerChallenge, OK),
9973 TestRound(kGetAuth, kSuccess, OK)}},
9974 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9975 { TestRound(kGet, kServerChallenge, OK),
9976 TestRound(kGetAuth, kFailure, kAuthErr)}},
9977 // Non-authenticating HTTPS server with a non-authenticating proxy.
9978 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
9979 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
9980 // Authenticating HTTPS server through a non-authenticating proxy.
9981 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
9982 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9983 TestRound(kGetAuth, kSuccess, OK)}},
9984 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
9985 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9986 TestRound(kGetAuth, kFailure, kAuthErr)}},
9987 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
9988 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9989 TestRound(kGetAuth, kSuccess, OK)}},
9990 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
9991 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
9992 TestRound(kGetAuth, kFailure, kAuthErr)}},
9993 // Non-Authenticating HTTPS server through an authenticating proxy.
9994 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
9995 { TestRound(kConnect, kProxyChallenge, OK),
9996 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
9997 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
9998 { TestRound(kConnect, kProxyChallenge, OK),
9999 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10000 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10001 { TestRound(kConnect, kProxyChallenge, OK),
10002 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10003 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10004 { TestRound(kConnect, kProxyChallenge, OK),
10005 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10006 // Authenticating HTTPS server through an authenticating proxy.
10007 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10008 { TestRound(kConnect, kProxyChallenge, OK),
10009 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10010 &kGet, &kServerChallenge),
10011 TestRound(kGetAuth, kSuccess, OK)}},
10012 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10013 { TestRound(kConnect, kProxyChallenge, OK),
10014 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10015 &kGet, &kServerChallenge),
10016 TestRound(kGetAuth, kFailure, kAuthErr)}},
10017 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10018 { TestRound(kConnect, kProxyChallenge, OK),
10019 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10020 &kGet, &kServerChallenge),
10021 TestRound(kGetAuth, kSuccess, OK)}},
10022 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10023 { TestRound(kConnect, kProxyChallenge, OK),
10024 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10025 &kGet, &kServerChallenge),
10026 TestRound(kGetAuth, kFailure, kAuthErr)}},
10027 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10028 { TestRound(kConnect, kProxyChallenge, OK),
10029 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10030 &kGet, &kServerChallenge),
10031 TestRound(kGetAuth, kSuccess, OK)}},
10032 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10033 { TestRound(kConnect, kProxyChallenge, OK),
10034 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10035 &kGet, &kServerChallenge),
10036 TestRound(kGetAuth, kFailure, kAuthErr)}},
10037 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10038 { TestRound(kConnect, kProxyChallenge, OK),
10039 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10040 &kGet, &kServerChallenge),
10041 TestRound(kGetAuth, kSuccess, OK)}},
10042 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10043 { TestRound(kConnect, kProxyChallenge, OK),
10044 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10045 &kGet, &kServerChallenge),
10046 TestRound(kGetAuth, kFailure, kAuthErr)}},
10047 };
10048
viettrungluue4a8b882014-10-16 06:17:3810049 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810050 HttpAuthHandlerMock::Factory* auth_factory(
10051 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710052 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510053 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610054
10055 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510056 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810057 for (int n = 0; n < 2; n++) {
10058 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10059 std::string auth_challenge = "Mock realm=proxy";
10060 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410061 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10062 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810063 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10064 origin, BoundNetLog());
10065 auth_handler->SetGenerateExpectation(
10066 test_config.proxy_auth_timing == AUTH_ASYNC,
10067 test_config.proxy_auth_rv);
10068 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10069 }
[email protected]044de0642010-06-17 10:42:1510070 }
10071 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010072 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510073 std::string auth_challenge = "Mock realm=server";
10074 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410075 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10076 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510077 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10078 origin, BoundNetLog());
10079 auth_handler->SetGenerateExpectation(
10080 test_config.server_auth_timing == AUTH_ASYNC,
10081 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810082 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510083 }
10084 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:0710085 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:1210086 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:1510087 } else {
[email protected]bb88e1d32013-05-03 23:11:0710088 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:1510089 }
10090
10091 HttpRequestInfo request;
10092 request.method = "GET";
10093 request.url = GURL(test_config.server_url);
10094 request.load_flags = 0;
10095
[email protected]bb88e1d32013-05-03 23:11:0710096 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110097 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510098
rchcb68dc62015-05-21 04:45:3610099 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
10100
10101 std::vector<std::vector<MockRead>> mock_reads(1);
10102 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1510103 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10104 const TestRound& read_write_round = test_config.rounds[round];
10105
10106 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3610107 mock_reads.back().push_back(read_write_round.read);
10108 mock_writes.back().push_back(read_write_round.write);
10109
10110 // kProxyChallenge uses Proxy-Connection: close which means that the
10111 // socket is closed and a new one will be created for the next request.
10112 if (read_write_round.read.data == kProxyChallenge.data &&
10113 read_write_round.write.data != kConnect.data) {
10114 mock_reads.push_back(std::vector<MockRead>());
10115 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1510116 }
10117
rchcb68dc62015-05-21 04:45:3610118 if (read_write_round.extra_read) {
10119 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1510120 }
rchcb68dc62015-05-21 04:45:3610121 if (read_write_round.extra_write) {
10122 mock_writes.back().push_back(*read_write_round.extra_write);
10123 }
[email protected]044de0642010-06-17 10:42:1510124
10125 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1510126 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710127 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510128 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3610129 }
[email protected]044de0642010-06-17 10:42:1510130
rchcb68dc62015-05-21 04:45:3610131 ScopedVector<StaticSocketDataProvider> data_providers;
10132 for (size_t i = 0; i < mock_reads.size(); ++i) {
10133 data_providers.push_back(new StaticSocketDataProvider(
10134 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
10135 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
10136 session_deps_.socket_factory->AddSocketDataProvider(
10137 data_providers.back());
10138 }
10139
10140 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10141 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1510142 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110143 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510144 int rv;
10145 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110146 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510147 } else {
[email protected]49639fa2011-12-20 23:22:4110148 rv = trans.RestartWithAuth(
10149 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510150 }
10151 if (rv == ERR_IO_PENDING)
10152 rv = callback.WaitForResult();
10153
10154 // Compare results with expected data.
10155 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010156 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5510157 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1510158 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10159 continue;
10160 }
10161 if (round + 1 < test_config.num_auth_rounds) {
10162 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10163 } else {
10164 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10165 }
10166 }
[email protected]e5ae96a2010-04-14 20:12:4510167 }
10168}
10169
[email protected]23e482282013-06-14 16:08:0210170TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410171 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410172 HttpAuthHandlerMock::Factory* auth_factory(
10173 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710174 session_deps_.http_auth_handler_factory.reset(auth_factory);
10175 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10176 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10177 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410178
10179 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10180 auth_handler->set_connection_based(true);
10181 std::string auth_challenge = "Mock realm=server";
10182 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410183 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10184 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410185 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10186 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810187 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410188
[email protected]c871bce92010-07-15 21:51:1410189 int rv = OK;
10190 const HttpResponseInfo* response = NULL;
10191 HttpRequestInfo request;
10192 request.method = "GET";
10193 request.url = origin;
10194 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710195
[email protected]bb88e1d32013-05-03 23:11:0710196 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010197
10198 // Use a TCP Socket Pool with only one connection per group. This is used
10199 // to validate that the TCP socket is not released to the pool between
10200 // each round of multi-round authentication.
10201 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810202 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010203 50, // Max sockets for pool
10204 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710205 session_deps_.host_resolver.get(),
10206 session_deps_.socket_factory.get(),
10207 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410208 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10209 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210210 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110211 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010212
[email protected]262eec82013-03-19 21:01:3610213 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010214 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110215 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410216
10217 const MockWrite kGet(
10218 "GET / HTTP/1.1\r\n"
10219 "Host: www.example.com\r\n"
10220 "Connection: keep-alive\r\n\r\n");
10221 const MockWrite kGetAuth(
10222 "GET / HTTP/1.1\r\n"
10223 "Host: www.example.com\r\n"
10224 "Connection: keep-alive\r\n"
10225 "Authorization: auth_token\r\n\r\n");
10226
10227 const MockRead kServerChallenge(
10228 "HTTP/1.1 401 Unauthorized\r\n"
10229 "WWW-Authenticate: Mock realm=server\r\n"
10230 "Content-Type: text/html; charset=iso-8859-1\r\n"
10231 "Content-Length: 14\r\n\r\n"
10232 "Unauthorized\r\n");
10233 const MockRead kSuccess(
10234 "HTTP/1.1 200 OK\r\n"
10235 "Content-Type: text/html; charset=iso-8859-1\r\n"
10236 "Content-Length: 3\r\n\r\n"
10237 "Yes");
10238
10239 MockWrite writes[] = {
10240 // First round
10241 kGet,
10242 // Second round
10243 kGetAuth,
10244 // Third round
10245 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010246 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010247 kGetAuth,
10248 // Competing request
10249 kGet,
[email protected]c871bce92010-07-15 21:51:1410250 };
10251 MockRead reads[] = {
10252 // First round
10253 kServerChallenge,
10254 // Second round
10255 kServerChallenge,
10256 // Third round
[email protected]eca50e122010-09-11 14:03:3010257 kServerChallenge,
10258 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410259 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010260 // Competing response
10261 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410262 };
10263 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10264 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710265 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410266
thestig9d3bb0c2015-01-24 00:49:5110267 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010268
10269 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410270 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110271 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410272 if (rv == ERR_IO_PENDING)
10273 rv = callback.WaitForResult();
10274 EXPECT_EQ(OK, rv);
10275 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010276 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410277 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810278 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410279
[email protected]7ef4cbbb2011-02-06 11:19:1010280 // In between rounds, another request comes in for the same domain.
10281 // It should not be able to grab the TCP socket that trans has already
10282 // claimed.
10283 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010284 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110285 TestCompletionCallback callback_compete;
10286 rv = trans_compete->Start(
10287 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010288 EXPECT_EQ(ERR_IO_PENDING, rv);
10289 // callback_compete.WaitForResult at this point would stall forever,
10290 // since the HttpNetworkTransaction does not release the request back to
10291 // the pool until after authentication completes.
10292
10293 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410294 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110295 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410296 if (rv == ERR_IO_PENDING)
10297 rv = callback.WaitForResult();
10298 EXPECT_EQ(OK, rv);
10299 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010300 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410301 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810302 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410303
[email protected]7ef4cbbb2011-02-06 11:19:1010304 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410305 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110306 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410307 if (rv == ERR_IO_PENDING)
10308 rv = callback.WaitForResult();
10309 EXPECT_EQ(OK, rv);
10310 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010311 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410312 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810313 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010314
[email protected]7ef4cbbb2011-02-06 11:19:1010315 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010316 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110317 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010318 if (rv == ERR_IO_PENDING)
10319 rv = callback.WaitForResult();
10320 EXPECT_EQ(OK, rv);
10321 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010322 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010323 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810324 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010325
10326 // Read the body since the fourth round was successful. This will also
10327 // release the socket back to the pool.
10328 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010329 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010330 if (rv == ERR_IO_PENDING)
10331 rv = callback.WaitForResult();
10332 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010333 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010334 EXPECT_EQ(0, rv);
10335 // There are still 0 idle sockets, since the trans_compete transaction
10336 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810337 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010338
10339 // The competing request can now finish. Wait for the headers and then
10340 // read the body.
10341 rv = callback_compete.WaitForResult();
10342 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010343 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010344 if (rv == ERR_IO_PENDING)
10345 rv = callback.WaitForResult();
10346 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010347 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010348 EXPECT_EQ(0, rv);
10349
10350 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810351 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410352}
10353
[email protected]65041fa2010-05-21 06:56:5310354// This tests the case that a request is issued via http instead of spdy after
10355// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210356TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]d7599122014-05-24 03:37:2310357 session_deps_.use_alternate_protocols = true;
10358 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610359 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310360 session_deps_.next_protos = next_protos;
10361
[email protected]65041fa2010-05-21 06:56:5310362 HttpRequestInfo request;
10363 request.method = "GET";
bncce36dca22015-04-21 22:11:2310364 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310365 request.load_flags = 0;
10366
10367 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310368 MockWrite(
10369 "GET / HTTP/1.1\r\n"
10370 "Host: www.example.org\r\n"
10371 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310372 };
10373
[email protected]8a0fc822013-06-27 20:52:4310374 std::string alternate_protocol_http_header =
10375 GetAlternateProtocolHttpHeader();
10376
[email protected]65041fa2010-05-21 06:56:5310377 MockRead data_reads[] = {
10378 MockRead("HTTP/1.1 200 OK\r\n"),
[email protected]8a0fc822013-06-27 20:52:4310379 MockRead(alternate_protocol_http_header.c_str()),
[email protected]65041fa2010-05-21 06:56:5310380 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610381 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310382 };
10383
[email protected]8ddf8322012-02-23 18:08:0610384 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810385 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310386
[email protected]bb88e1d32013-05-03 23:11:0710387 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310388
10389 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10390 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710391 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310392
[email protected]49639fa2011-12-20 23:22:4110393 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310394
[email protected]bb88e1d32013-05-03 23:11:0710395 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610396 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010397 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310398
[email protected]49639fa2011-12-20 23:22:4110399 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310400
10401 EXPECT_EQ(ERR_IO_PENDING, rv);
10402 EXPECT_EQ(OK, callback.WaitForResult());
10403
10404 const HttpResponseInfo* response = trans->GetResponseInfo();
10405 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010406 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310407 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10408
10409 std::string response_data;
10410 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10411 EXPECT_EQ("hello world", response_data);
10412
10413 EXPECT_FALSE(response->was_fetched_via_spdy);
10414 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310415}
[email protected]26ef6582010-06-24 02:30:4710416
[email protected]23e482282013-06-14 16:08:0210417TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4710418 // Simulate the SSL handshake completing with an NPN negotiation
10419 // followed by an immediate server closing of the socket.
10420 // Fix crash: http://crbug.com/46369
[email protected]d7599122014-05-24 03:37:2310421 session_deps_.use_alternate_protocols = true;
10422 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710423
10424 HttpRequestInfo request;
10425 request.method = "GET";
bncce36dca22015-04-21 22:11:2310426 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710427 request.load_flags = 0;
10428
[email protected]8ddf8322012-02-23 18:08:0610429 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210430 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710432
[email protected]cdf8f7e72013-05-23 10:56:4610433 scoped_ptr<SpdyFrame> req(
10434 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310435 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710436
10437 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610438 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710439 };
10440
rch8e6c6c42015-05-01 14:05:1310441 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10442 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710443 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710444
[email protected]49639fa2011-12-20 23:22:4110445 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710446
[email protected]bb88e1d32013-05-03 23:11:0710447 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610448 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010449 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710450
[email protected]49639fa2011-12-20 23:22:4110451 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710452 EXPECT_EQ(ERR_IO_PENDING, rv);
10453 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710454}
[email protected]65d34382010-07-01 18:12:2610455
[email protected]795cbf82013-07-22 09:37:2710456// A subclass of HttpAuthHandlerMock that records the request URL when
10457// it gets it. This is needed since the auth handler may get destroyed
10458// before we get a chance to query it.
10459class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10460 public:
10461 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10462
dchengb03027d2014-10-21 12:00:2010463 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710464
10465 protected:
dchengb03027d2014-10-21 12:00:2010466 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10467 const HttpRequestInfo* request,
10468 const CompletionCallback& callback,
10469 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710470 *url_ = request->url;
10471 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10472 credentials, request, callback, auth_token);
10473 }
10474
10475 private:
10476 GURL* url_;
10477};
10478
[email protected]23e482282013-06-14 16:08:0210479TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
[email protected]f45c1ee2010-08-03 00:54:3010480 // This test ensures that the URL passed into the proxy is upgraded
10481 // to https when doing an Alternate Protocol upgrade.
[email protected]d7599122014-05-24 03:37:2310482 session_deps_.use_alternate_protocols = true;
10483 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010484
[email protected]bb88e1d32013-05-03 23:11:0710485 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010486 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110487 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710488 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710489 GURL request_url;
10490 {
10491 HttpAuthHandlerMock::Factory* auth_factory =
10492 new HttpAuthHandlerMock::Factory();
10493 UrlRecordingHttpAuthHandlerMock* auth_handler =
10494 new UrlRecordingHttpAuthHandlerMock(&request_url);
10495 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10496 auth_factory->set_do_init_from_challenge(true);
10497 session_deps_.http_auth_handler_factory.reset(auth_factory);
10498 }
[email protected]f45c1ee2010-08-03 00:54:3010499
10500 HttpRequestInfo request;
10501 request.method = "GET";
bncce36dca22015-04-21 22:11:2310502 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3010503 request.load_flags = 0;
10504
10505 // First round goes unauthenticated through the proxy.
10506 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2310507 MockWrite(
10508 "GET http://www.example.org/ HTTP/1.1\r\n"
10509 "Host: www.example.org\r\n"
10510 "Proxy-Connection: keep-alive\r\n"
10511 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010512 };
10513 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610514 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810515 MockRead("HTTP/1.1 200 OK\r\n"),
10516 MockRead("Alternate-Protocol: 443:"),
10517 MockRead(GetAlternateProtocolFromParam()),
10518 MockRead("\r\n"),
10519 MockRead("Proxy-Connection: close\r\n"),
10520 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010521 };
10522 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10523 data_writes_1, arraysize(data_writes_1));
10524
bncce36dca22015-04-21 22:11:2310525 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3010526 // Alternate-Protocol announcement in the first round. It fails due
10527 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2310528 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5910529 // Proxy-Authorization headers. There is then a SPDY request round.
10530 //
[email protected]fe3b7dc2012-02-03 19:52:0910531 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10532 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10533 // does a Disconnect and Connect on the same socket, rather than trying
10534 // to obtain a new one.
10535 //
[email protected]394816e92010-08-03 07:38:5910536 // NOTE: Originally, the proxy response to the second CONNECT request
10537 // simply returned another 407 so the unit test could skip the SSL connection
10538 // establishment and SPDY framing issues. Alas, the
10539 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010540 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910541
[email protected]cdf8f7e72013-05-23 10:56:4610542 scoped_ptr<SpdyFrame> req(
10543 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210544 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10545 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010546
[email protected]394816e92010-08-03 07:38:5910547 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2310548 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310549 MockWrite(ASYNC, 0,
10550 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10551 "Host: www.example.org\r\n"
10552 "Proxy-Connection: keep-alive\r\n"
10553 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910554
bncce36dca22015-04-21 22:11:2310555 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310556 MockWrite(ASYNC, 2,
10557 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10558 "Host: www.example.org\r\n"
10559 "Proxy-Connection: keep-alive\r\n"
10560 "Proxy-Authorization: auth_token\r\n"
10561 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010562
bncce36dca22015-04-21 22:11:2310563 // SPDY request
rch8e6c6c42015-05-01 14:05:1310564 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3010565 };
[email protected]394816e92010-08-03 07:38:5910566 const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
10567 "Proxy-Authenticate: Mock\r\n"
10568 "Proxy-Connection: close\r\n"
10569 "\r\n");
10570 const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10571 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1310572 // First connection attempt fails
10573 MockRead(ASYNC, kRejectConnectResponse,
10574 arraysize(kRejectConnectResponse) - 1, 1),
[email protected]394816e92010-08-03 07:38:5910575
rch8e6c6c42015-05-01 14:05:1310576 // Second connection attempt passes
10577 MockRead(ASYNC, kAcceptConnectResponse,
10578 arraysize(kAcceptConnectResponse) - 1, 3),
[email protected]394816e92010-08-03 07:38:5910579
rch8e6c6c42015-05-01 14:05:1310580 // SPDY response
10581 CreateMockRead(*resp.get(), 5),
10582 CreateMockRead(*data.get(), 6),
10583 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5910584 };
rch8e6c6c42015-05-01 14:05:1310585 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
10586 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010587
[email protected]8ddf8322012-02-23 18:08:0610588 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210589 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310590 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10591 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3010592
[email protected]d973e99a2012-02-17 21:02:3610593 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510594 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10595 NULL, 0, NULL, 0);
10596 hanging_non_alternate_protocol_socket.set_connect_data(
10597 never_finishing_connect);
10598
[email protected]bb88e1d32013-05-03 23:11:0710599 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10600 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10601 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10602 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510603 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0710604 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3010605
10606 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4110607 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3610608 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5010609 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110610 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010611 EXPECT_EQ(ERR_IO_PENDING, rv);
10612 EXPECT_EQ(OK, callback_1.WaitForResult());
10613
10614 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4110615 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3610616 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5010617 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110618 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3010619 EXPECT_EQ(ERR_IO_PENDING, rv);
10620 EXPECT_EQ(OK, callback_2.WaitForResult());
10621 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010622 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3010623 ASSERT_FALSE(response->auth_challenge.get() == NULL);
10624
10625 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4110626 TestCompletionCallback callback_3;
10627 rv = trans_2->RestartWithAuth(
10628 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3010629 EXPECT_EQ(ERR_IO_PENDING, rv);
10630 EXPECT_EQ(OK, callback_3.WaitForResult());
10631
10632 // After all that work, these two lines (or actually, just the scheme) are
10633 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3010634 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2310635 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3010636
[email protected]029c83b62013-01-24 05:28:2010637 LoadTimingInfo load_timing_info;
10638 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
10639 TestLoadTimingNotReusedWithPac(load_timing_info,
10640 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3810641}
10642
10643// Test that if we cancel the transaction as the connection is completing, that
10644// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0210645TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3810646 // Setup everything about the connection to complete synchronously, so that
10647 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
10648 // for is the callback from the HttpStreamRequest.
10649 // Then cancel the transaction.
10650 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3610651 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3810652 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610653 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
10654 MockRead(SYNCHRONOUS, "hello world"),
10655 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3810656 };
10657
[email protected]8e6441ca2010-08-19 05:56:3810658 HttpRequestInfo request;
10659 request.method = "GET";
bncce36dca22015-04-21 22:11:2310660 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3810661 request.load_flags = 0;
10662
[email protected]bb88e1d32013-05-03 23:11:0710663 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0710664 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2710665 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4110666 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2710667
[email protected]8e6441ca2010-08-19 05:56:3810668 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10669 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710670 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3810671
[email protected]49639fa2011-12-20 23:22:4110672 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3810673
vishal.b62985ca92015-04-17 08:45:5110674 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4110675 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3810676 EXPECT_EQ(ERR_IO_PENDING, rv);
10677 trans.reset(); // Cancel the transaction here.
10678
[email protected]2da659e2013-05-23 20:51:3410679 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3010680}
10681
[email protected]ecab6e052014-05-16 14:58:1210682// Test that if a transaction is cancelled after receiving the headers, the
10683// stream is drained properly and added back to the socket pool. The main
10684// purpose of this test is to make sure that an HttpStreamParser can be read
10685// from after the HttpNetworkTransaction and the objects it owns have been
10686// deleted.
10687// See http://crbug.com/368418
10688TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10689 MockRead data_reads[] = {
10690 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10691 MockRead(ASYNC, "Content-Length: 2\r\n"),
10692 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10693 MockRead(ASYNC, "1"),
10694 // 2 async reads are necessary to trigger a ReadResponseBody call after the
10695 // HttpNetworkTransaction has been deleted.
10696 MockRead(ASYNC, "2"),
10697 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
10698 };
10699 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10700 session_deps_.socket_factory->AddSocketDataProvider(&data);
10701
10702 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10703
10704 {
10705 HttpRequestInfo request;
10706 request.method = "GET";
bncce36dca22015-04-21 22:11:2310707 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1210708 request.load_flags = 0;
10709
dcheng48459ac22014-08-26 00:46:4110710 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1210711 TestCompletionCallback callback;
10712
10713 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10714 EXPECT_EQ(ERR_IO_PENDING, rv);
10715 callback.WaitForResult();
10716
10717 const HttpResponseInfo* response = trans.GetResponseInfo();
10718 ASSERT_TRUE(response != NULL);
10719 EXPECT_TRUE(response->headers.get() != NULL);
10720 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10721
10722 // The transaction and HttpRequestInfo are deleted.
10723 }
10724
10725 // Let the HttpResponseBodyDrainer drain the socket.
10726 base::MessageLoop::current()->RunUntilIdle();
10727
10728 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4110729 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1210730}
10731
[email protected]76a505b2010-08-25 06:23:0010732// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210733TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0710734 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010735 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110736 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710737 session_deps_.net_log = log.bound().net_log();
10738 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010739
[email protected]76a505b2010-08-25 06:23:0010740 HttpRequestInfo request;
10741 request.method = "GET";
bncce36dca22015-04-21 22:11:2310742 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010743
10744 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310745 MockWrite(
10746 "GET http://www.example.org/ HTTP/1.1\r\n"
10747 "Host: www.example.org\r\n"
10748 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010749 };
10750
10751 MockRead data_reads1[] = {
10752 MockRead("HTTP/1.1 200 OK\r\n"),
10753 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10754 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610755 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010756 };
10757
10758 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10759 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710760 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0010761
[email protected]49639fa2011-12-20 23:22:4110762 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010763
[email protected]262eec82013-03-19 21:01:3610764 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010765 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2710766 BeforeProxyHeadersSentHandler proxy_headers_handler;
10767 trans->SetBeforeProxyHeadersSentCallback(
10768 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10769 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5010770
[email protected]49639fa2011-12-20 23:22:4110771 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010772 EXPECT_EQ(ERR_IO_PENDING, rv);
10773
10774 rv = callback1.WaitForResult();
10775 EXPECT_EQ(OK, rv);
10776
10777 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010778 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010779
10780 EXPECT_TRUE(response->headers->IsKeepAlive());
10781 EXPECT_EQ(200, response->headers->response_code());
10782 EXPECT_EQ(100, response->headers->GetContentLength());
10783 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510784 EXPECT_TRUE(
10785 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2710786 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10787 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0010788 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2010789
10790 LoadTimingInfo load_timing_info;
10791 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10792 TestLoadTimingNotReusedWithPac(load_timing_info,
10793 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0010794}
10795
10796// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0210797TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0710798 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010799 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110800 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710801 session_deps_.net_log = log.bound().net_log();
10802 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010803
[email protected]76a505b2010-08-25 06:23:0010804 HttpRequestInfo request;
10805 request.method = "GET";
bncce36dca22015-04-21 22:11:2310806 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010807
10808 // Since we have proxy, should try to establish tunnel.
10809 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310810 MockWrite(
10811 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10812 "Host: www.example.org\r\n"
10813 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010814
bncce36dca22015-04-21 22:11:2310815 MockWrite(
10816 "GET / HTTP/1.1\r\n"
10817 "Host: www.example.org\r\n"
10818 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010819 };
10820
10821 MockRead data_reads1[] = {
10822 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
10823
10824 MockRead("HTTP/1.1 200 OK\r\n"),
10825 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10826 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610827 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0010828 };
10829
10830 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10831 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710832 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610833 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710834 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010835
[email protected]49639fa2011-12-20 23:22:4110836 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010837
[email protected]262eec82013-03-19 21:01:3610838 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010839 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010840
[email protected]49639fa2011-12-20 23:22:4110841 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010842 EXPECT_EQ(ERR_IO_PENDING, rv);
10843
10844 rv = callback1.WaitForResult();
10845 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4610846 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010847 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010848 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010849 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010850 NetLog::PHASE_NONE);
10851 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010852 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010853 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10854 NetLog::PHASE_NONE);
10855
10856 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010857 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0010858
10859 EXPECT_TRUE(response->headers->IsKeepAlive());
10860 EXPECT_EQ(200, response->headers->response_code());
10861 EXPECT_EQ(100, response->headers->GetContentLength());
10862 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10863 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1510864 EXPECT_TRUE(
10865 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2010866
10867 LoadTimingInfo load_timing_info;
10868 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10869 TestLoadTimingNotReusedWithPac(load_timing_info,
10870 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0010871}
10872
10873// Test a basic HTTPS GET request through a proxy, but the server hangs up
10874// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0210875TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0710876 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110877 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710878 session_deps_.net_log = log.bound().net_log();
10879 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0010880
[email protected]76a505b2010-08-25 06:23:0010881 HttpRequestInfo request;
10882 request.method = "GET";
bncce36dca22015-04-21 22:11:2310883 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0010884
10885 // Since we have proxy, should try to establish tunnel.
10886 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310887 MockWrite(
10888 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10889 "Host: www.example.org\r\n"
10890 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010891
bncce36dca22015-04-21 22:11:2310892 MockWrite(
10893 "GET / HTTP/1.1\r\n"
10894 "Host: www.example.org\r\n"
10895 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0010896 };
10897
10898 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0610899 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0010900 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610901 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0010902 };
10903
10904 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10905 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0710906 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0610907 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710908 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0010909
[email protected]49639fa2011-12-20 23:22:4110910 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0010911
[email protected]262eec82013-03-19 21:01:3610912 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010913 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5010914
[email protected]49639fa2011-12-20 23:22:4110915 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0010916 EXPECT_EQ(ERR_IO_PENDING, rv);
10917
10918 rv = callback1.WaitForResult();
10919 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4610920 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4010921 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0010922 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010923 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0010924 NetLog::PHASE_NONE);
10925 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4010926 entries, pos,
[email protected]76a505b2010-08-25 06:23:0010927 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
10928 NetLog::PHASE_NONE);
10929}
10930
[email protected]749eefa82010-09-13 22:14:0310931// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0210932TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4610933 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2310934 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1310935 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0310936
[email protected]23e482282013-06-14 16:08:0210937 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10938 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0310939 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310940 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0310941 };
10942
rch8e6c6c42015-05-01 14:05:1310943 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10944 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710945 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0310946
[email protected]8ddf8322012-02-23 18:08:0610947 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210948 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710949 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0310950
[email protected]bb88e1d32013-05-03 23:11:0710951 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0310952
10953 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310954 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010955 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310956 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710957 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610958 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310959
10960 HttpRequestInfo request;
10961 request.method = "GET";
bncce36dca22015-04-21 22:11:2310962 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0310963 request.load_flags = 0;
10964
10965 // This is the important line that marks this as a preconnect.
10966 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
10967
[email protected]262eec82013-03-19 21:01:3610968 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010969 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0310970
[email protected]41d64e82013-07-03 22:44:2610971 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4110972 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0310973 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110974 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0310975}
10976
[email protected]73b8dd222010-11-11 19:55:2410977// Given a net error, cause that error to be returned from the first Write()
10978// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0210979void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0710980 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2910981 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2710982 request_info.url = GURL("https://www.example.com/");
10983 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2910984 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2710985
[email protected]8ddf8322012-02-23 18:08:0610986 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2910987 MockWrite data_writes[] = {
10988 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2410989 };
ttuttle859dc7a2015-04-23 19:42:2910990 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710991 session_deps_.socket_factory->AddSocketDataProvider(&data);
10992 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2410993
[email protected]bb88e1d32013-05-03 23:11:0710994 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610995 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010996 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2410997
[email protected]49639fa2011-12-20 23:22:4110998 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2910999 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11000 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2411001 rv = callback.WaitForResult();
11002 ASSERT_EQ(error, rv);
11003}
11004
[email protected]23e482282013-06-14 16:08:0211005TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411006 // Just check a grab bag of cert errors.
11007 static const int kErrors[] = {
11008 ERR_CERT_COMMON_NAME_INVALID,
11009 ERR_CERT_AUTHORITY_INVALID,
11010 ERR_CERT_DATE_INVALID,
11011 };
11012 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611013 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11014 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411015 }
11016}
11017
[email protected]bd0b6772011-01-11 19:59:3011018// Ensure that a client certificate is removed from the SSL client auth
11019// cache when:
11020// 1) No proxy is involved.
11021// 2) TLS False Start is disabled.
11022// 3) The initial TLS handshake requests a client certificate.
11023// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211024TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311025 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911026 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711027 request_info.url = GURL("https://www.example.com/");
11028 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911029 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711030
[email protected]bd0b6772011-01-11 19:59:3011031 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111032 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011033
11034 // [ssl_]data1 contains the data for the first SSL handshake. When a
11035 // CertificateRequest is received for the first time, the handshake will
11036 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911037 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011038 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711039 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911040 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711041 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011042
11043 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11044 // False Start is not being used, the result of the SSL handshake will be
11045 // returned as part of the SSLClientSocket::Connect() call. This test
11046 // matches the result of a server sending a handshake_failure alert,
11047 // rather than a Finished message, because it requires a client
11048 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911049 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011050 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911052 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711053 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011054
11055 // [ssl_]data3 contains the data for the third SSL handshake. When a
11056 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211057 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
11058 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011059 // of the HttpNetworkTransaction. Because this test failure is due to
11060 // requiring a client certificate, this fallback handshake should also
11061 // fail.
ttuttle859dc7a2015-04-23 19:42:2911062 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011063 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711064 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911065 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711066 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011067
[email protected]80c75f682012-05-26 16:22:1711068 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
11069 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211070 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
11071 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1711072 // of the HttpNetworkTransaction. Because this test failure is due to
11073 // requiring a client certificate, this fallback handshake should also
11074 // fail.
ttuttle859dc7a2015-04-23 19:42:2911075 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711076 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711077 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911078 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711079 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711080
[email protected]bb88e1d32013-05-03 23:11:0711081 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611082 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011083 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011084
[email protected]bd0b6772011-01-11 19:59:3011085 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111086 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911087 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11088 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011089
11090 // Complete the SSL handshake, which should abort due to requiring a
11091 // client certificate.
11092 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911093 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011094
11095 // Indicate that no certificate should be supplied. From the perspective
11096 // of SSLClientCertCache, NULL is just as meaningful as a real
11097 // certificate, so this is the same as supply a
11098 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111099 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911100 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011101
11102 // Ensure the certificate was added to the client auth cache before
11103 // allowing the connection to continue restarting.
11104 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111105 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11106 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011107 ASSERT_EQ(NULL, client_cert.get());
11108
11109 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711110 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11111 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011112 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911113 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011114
11115 // Ensure that the client certificate is removed from the cache on a
11116 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111117 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11118 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011119}
11120
11121// Ensure that a client certificate is removed from the SSL client auth
11122// cache when:
11123// 1) No proxy is involved.
11124// 2) TLS False Start is enabled.
11125// 3) The initial TLS handshake requests a client certificate.
11126// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211127TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311128 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911129 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711130 request_info.url = GURL("https://www.example.com/");
11131 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911132 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711133
[email protected]bd0b6772011-01-11 19:59:3011134 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111135 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011136
11137 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11138 // return successfully after reading up to the peer's Certificate message.
11139 // This is to allow the caller to call SSLClientSocket::Write(), which can
11140 // enqueue application data to be sent in the same packet as the
11141 // ChangeCipherSpec and Finished messages.
11142 // The actual handshake will be finished when SSLClientSocket::Read() is
11143 // called, which expects to process the peer's ChangeCipherSpec and
11144 // Finished messages. If there was an error negotiating with the peer,
11145 // such as due to the peer requiring a client certificate when none was
11146 // supplied, the alert sent by the peer won't be processed until Read() is
11147 // called.
11148
11149 // Like the non-False Start case, when a client certificate is requested by
11150 // the peer, the handshake is aborted during the Connect() call.
11151 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911152 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011153 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711154 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911155 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711156 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011157
11158 // When a client certificate is supplied, Connect() will not be aborted
11159 // when the peer requests the certificate. Instead, the handshake will
11160 // artificially succeed, allowing the caller to write the HTTP request to
11161 // the socket. The handshake messages are not processed until Read() is
11162 // called, which then detects that the handshake was aborted, due to the
11163 // peer sending a handshake_failure because it requires a client
11164 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911165 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011166 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711167 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911168 MockRead data2_reads[] = {
11169 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011170 };
ttuttle859dc7a2015-04-23 19:42:2911171 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711172 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011173
11174 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711175 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11176 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911177 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011178 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711179 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911180 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711181 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011182
[email protected]80c75f682012-05-26 16:22:1711183 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11184 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911185 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711186 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711187 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911188 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711189 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711190
[email protected]7799de12013-05-30 05:52:5111191 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911192 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111193 ssl_data5.cert_request_info = cert_request.get();
11194 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911195 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111196 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11197
[email protected]bb88e1d32013-05-03 23:11:0711198 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611199 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011200 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011201
[email protected]bd0b6772011-01-11 19:59:3011202 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111203 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911204 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11205 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011206
11207 // Complete the SSL handshake, which should abort due to requiring a
11208 // client certificate.
11209 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911210 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011211
11212 // Indicate that no certificate should be supplied. From the perspective
11213 // of SSLClientCertCache, NULL is just as meaningful as a real
11214 // certificate, so this is the same as supply a
11215 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111216 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911217 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011218
11219 // Ensure the certificate was added to the client auth cache before
11220 // allowing the connection to continue restarting.
11221 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111222 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11223 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011224 ASSERT_EQ(NULL, client_cert.get());
11225
[email protected]bd0b6772011-01-11 19:59:3011226 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711227 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11228 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011229 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911230 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011231
11232 // Ensure that the client certificate is removed from the cache on a
11233 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111234 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11235 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011236}
11237
[email protected]8c405132011-01-11 22:03:1811238// Ensure that a client certificate is removed from the SSL client auth
11239// cache when:
11240// 1) An HTTPS proxy is involved.
11241// 3) The HTTPS proxy requests a client certificate.
11242// 4) The client supplies an invalid/unacceptable certificate for the
11243// proxy.
11244// The test is repeated twice, first for connecting to an HTTPS endpoint,
11245// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211246TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711247 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811248 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:5111249 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711250 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811251
11252 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111253 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811254
11255 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11256 // [ssl_]data[1-3]. Rather than represending the endpoint
11257 // (www.example.com:443), they represent failures with the HTTPS proxy
11258 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911259 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811260 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711261 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911262 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711263 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811264
ttuttle859dc7a2015-04-23 19:42:2911265 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811266 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711267 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911268 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711269 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811270
[email protected]80c75f682012-05-26 16:22:1711271 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11272#if 0
ttuttle859dc7a2015-04-23 19:42:2911273 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811274 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711275 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911276 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711277 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711278#endif
[email protected]8c405132011-01-11 22:03:1811279
ttuttle859dc7a2015-04-23 19:42:2911280 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811281 requests[0].url = GURL("https://www.example.com/");
11282 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911283 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811284
11285 requests[1].url = GURL("http://www.example.com/");
11286 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911287 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811288
11289 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711290 session_deps_.socket_factory->ResetNextMockIndexes();
11291 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811292 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011293 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811294
11295 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111296 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911297 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11298 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811299
11300 // Complete the SSL handshake, which should abort due to requiring a
11301 // client certificate.
11302 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911303 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811304
11305 // Indicate that no certificate should be supplied. From the perspective
11306 // of SSLClientCertCache, NULL is just as meaningful as a real
11307 // certificate, so this is the same as supply a
11308 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111309 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911310 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811311
11312 // Ensure the certificate was added to the client auth cache before
11313 // allowing the connection to continue restarting.
11314 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111315 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11316 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811317 ASSERT_EQ(NULL, client_cert.get());
11318 // Ensure the certificate was NOT cached for the endpoint. This only
11319 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111320 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11321 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811322
11323 // Restart the handshake. This will consume ssl_data2, which fails, and
11324 // then consume ssl_data3, which should also fail. The result code is
11325 // checked against what ssl_data3 should return.
11326 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911327 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811328
11329 // Now that the new handshake has failed, ensure that the client
11330 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111331 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11332 HostPortPair("proxy", 70), &client_cert));
11333 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11334 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811335 }
11336}
11337
mmenke5c642132015-06-02 16:05:1311338TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]d7599122014-05-24 03:37:2311339 session_deps_.use_alternate_protocols = true;
11340 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611341
11342 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711343 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11344 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611345 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11346 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611347
[email protected]8ddf8322012-02-23 18:08:0611348 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211349 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711350 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611351
[email protected]cdf8f7e72013-05-23 10:56:4611352 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311353 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611354 scoped_ptr<SpdyFrame> host2_req(
11355 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611356 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311357 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611358 };
[email protected]23e482282013-06-14 16:08:0211359 scoped_ptr<SpdyFrame> host1_resp(
11360 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11361 scoped_ptr<SpdyFrame> host1_resp_body(
11362 spdy_util_.ConstructSpdyBodyFrame(1, true));
11363 scoped_ptr<SpdyFrame> host2_resp(
11364 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11365 scoped_ptr<SpdyFrame> host2_resp_body(
11366 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611367 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311368 CreateMockRead(*host1_resp, 1),
11369 CreateMockRead(*host1_resp_body, 2),
11370 CreateMockRead(*host2_resp, 4),
11371 CreateMockRead(*host2_resp_body, 5),
11372 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611373 };
11374
[email protected]d2b5f092012-06-08 23:55:0211375 IPAddressNumber ip;
11376 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11377 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11378 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311379 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11380 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711381 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611382
[email protected]aa22b242011-11-16 18:58:2911383 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611384 HttpRequestInfo request1;
11385 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311386 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611387 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011388 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611389
[email protected]49639fa2011-12-20 23:22:4111390 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611391 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111392 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611393
11394 const HttpResponseInfo* response = trans1.GetResponseInfo();
11395 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011396 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611397 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11398
11399 std::string response_data;
11400 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11401 EXPECT_EQ("hello!", response_data);
11402
11403 // Preload www.gmail.com into HostCache.
11404 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011405 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611406 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011407 rv = session_deps_.host_resolver->Resolve(resolve_info,
11408 DEFAULT_PRIORITY,
11409 &ignored,
11410 callback.callback(),
11411 NULL,
11412 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711413 EXPECT_EQ(ERR_IO_PENDING, rv);
11414 rv = callback.WaitForResult();
11415 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611416
11417 HttpRequestInfo request2;
11418 request2.method = "GET";
11419 request2.url = GURL("https://www.gmail.com/");
11420 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011421 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611422
[email protected]49639fa2011-12-20 23:22:4111423 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611424 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111425 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611426
11427 response = trans2.GetResponseInfo();
11428 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011429 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611430 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11431 EXPECT_TRUE(response->was_fetched_via_spdy);
11432 EXPECT_TRUE(response->was_npn_negotiated);
11433 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11434 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611435}
11436
[email protected]23e482282013-06-14 16:08:0211437TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d7599122014-05-24 03:37:2311438 session_deps_.use_alternate_protocols = true;
11439 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211440
11441 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711442 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11443 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211444 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11445 pool_peer.DisableDomainAuthenticationVerification();
11446
11447 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211448 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711449 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211450
[email protected]cdf8f7e72013-05-23 10:56:4611451 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311452 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611453 scoped_ptr<SpdyFrame> host2_req(
11454 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211455 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311456 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0211457 };
[email protected]23e482282013-06-14 16:08:0211458 scoped_ptr<SpdyFrame> host1_resp(
11459 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11460 scoped_ptr<SpdyFrame> host1_resp_body(
11461 spdy_util_.ConstructSpdyBodyFrame(1, true));
11462 scoped_ptr<SpdyFrame> host2_resp(
11463 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11464 scoped_ptr<SpdyFrame> host2_resp_body(
11465 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211466 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311467 CreateMockRead(*host1_resp, 1),
11468 CreateMockRead(*host1_resp_body, 2),
11469 CreateMockRead(*host2_resp, 4),
11470 CreateMockRead(*host2_resp_body, 5),
11471 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0211472 };
11473
11474 IPAddressNumber ip;
11475 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11476 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11477 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311478 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11479 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711480 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211481
11482 TestCompletionCallback callback;
11483 HttpRequestInfo request1;
11484 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311485 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0211486 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011487 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211488
11489 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11490 EXPECT_EQ(ERR_IO_PENDING, rv);
11491 EXPECT_EQ(OK, callback.WaitForResult());
11492
11493 const HttpResponseInfo* response = trans1.GetResponseInfo();
11494 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011495 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211496 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11497
11498 std::string response_data;
11499 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11500 EXPECT_EQ("hello!", response_data);
11501
11502 HttpRequestInfo request2;
11503 request2.method = "GET";
11504 request2.url = GURL("https://www.gmail.com/");
11505 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011506 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211507
11508 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11509 EXPECT_EQ(ERR_IO_PENDING, rv);
11510 EXPECT_EQ(OK, callback.WaitForResult());
11511
11512 response = trans2.GetResponseInfo();
11513 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011514 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211515 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11516 EXPECT_TRUE(response->was_fetched_via_spdy);
11517 EXPECT_TRUE(response->was_npn_negotiated);
11518 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11519 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211520}
11521
ttuttle859dc7a2015-04-23 19:42:2911522class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4611523 public:
11524 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11525 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011526 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611527
11528 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11529
11530 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011531 int Resolve(const RequestInfo& info,
11532 RequestPriority priority,
11533 AddressList* addresses,
11534 const CompletionCallback& callback,
11535 RequestHandle* out_req,
11536 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011537 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011538 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011539 }
11540
dchengb03027d2014-10-21 12:00:2011541 int ResolveFromCache(const RequestInfo& info,
11542 AddressList* addresses,
11543 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011544 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11545 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911546 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611547 return rv;
11548 }
11549
dchengb03027d2014-10-21 12:00:2011550 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611551 host_resolver_.CancelRequest(req);
11552 }
11553
[email protected]46da33be2011-07-19 21:58:0411554 MockCachingHostResolver* GetMockHostResolver() {
11555 return &host_resolver_;
11556 }
11557
[email protected]e3ceb682011-06-28 23:55:4611558 private:
11559 MockCachingHostResolver host_resolver_;
11560 const HostPortPair host_port_;
11561};
11562
mmenke5c642132015-06-02 16:05:1311563TEST_P(HttpNetworkTransactionTest,
11564 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]d7599122014-05-24 03:37:2311565 session_deps_.use_alternate_protocols = true;
11566 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611567
11568 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611569 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411570 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711571 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611572 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711573 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611574 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11575 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611576
[email protected]8ddf8322012-02-23 18:08:0611577 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211578 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711579 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611580
[email protected]cdf8f7e72013-05-23 10:56:4611581 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311582 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611583 scoped_ptr<SpdyFrame> host2_req(
11584 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611585 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311586 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611587 };
[email protected]23e482282013-06-14 16:08:0211588 scoped_ptr<SpdyFrame> host1_resp(
11589 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11590 scoped_ptr<SpdyFrame> host1_resp_body(
11591 spdy_util_.ConstructSpdyBodyFrame(1, true));
11592 scoped_ptr<SpdyFrame> host2_resp(
11593 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11594 scoped_ptr<SpdyFrame> host2_resp_body(
11595 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611596 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311597 CreateMockRead(*host1_resp, 1),
11598 CreateMockRead(*host1_resp_body, 2),
11599 CreateMockRead(*host2_resp, 4),
11600 CreateMockRead(*host2_resp_body, 5),
11601 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611602 };
11603
[email protected]d2b5f092012-06-08 23:55:0211604 IPAddressNumber ip;
11605 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11606 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11607 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311608 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11609 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711610 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611611
[email protected]aa22b242011-11-16 18:58:2911612 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611613 HttpRequestInfo request1;
11614 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311615 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611616 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011617 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611618
[email protected]49639fa2011-12-20 23:22:4111619 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611620 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111621 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611622
11623 const HttpResponseInfo* response = trans1.GetResponseInfo();
11624 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011625 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611626 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11627
11628 std::string response_data;
11629 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11630 EXPECT_EQ("hello!", response_data);
11631
11632 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1011633 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4611634 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011635 rv = host_resolver.Resolve(resolve_info,
11636 DEFAULT_PRIORITY,
11637 &ignored,
11638 callback.callback(),
11639 NULL,
11640 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711641 EXPECT_EQ(ERR_IO_PENDING, rv);
11642 rv = callback.WaitForResult();
11643 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611644
11645 HttpRequestInfo request2;
11646 request2.method = "GET";
11647 request2.url = GURL("https://www.gmail.com/");
11648 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011649 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611650
[email protected]49639fa2011-12-20 23:22:4111651 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611652 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111653 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611654
11655 response = trans2.GetResponseInfo();
11656 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011657 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611658 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11659 EXPECT_TRUE(response->was_fetched_via_spdy);
11660 EXPECT_TRUE(response->was_npn_negotiated);
11661 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11662 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611663}
11664
[email protected]23e482282013-06-14 16:08:0211665TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2311666 const std::string https_url = "https://www.example.org:8080/";
11667 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0411668
11669 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4611670 scoped_ptr<SpdyFrame> req1(
11671 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0411672
11673 MockWrite writes1[] = {
11674 CreateMockWrite(*req1, 0),
11675 };
11676
[email protected]23e482282013-06-14 16:08:0211677 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11678 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0411679 MockRead reads1[] = {
11680 CreateMockRead(*resp1, 1),
11681 CreateMockRead(*body1, 2),
11682 MockRead(ASYNC, ERR_IO_PENDING, 3)
11683 };
11684
rch8e6c6c42015-05-01 14:05:1311685 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
11686 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0411687 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5711688 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0411689
11690 // HTTP GET for the HTTP URL
11691 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1311692 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3411693 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2311694 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3411695 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0411696 };
11697
11698 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1311699 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
11700 MockRead(ASYNC, 2, "hello"),
11701 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0411702 };
11703
rch8e6c6c42015-05-01 14:05:1311704 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
11705 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0411706
[email protected]8450d722012-07-02 19:14:0411707 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211708 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711709 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11710 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11711 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0411712
[email protected]bb88e1d32013-05-03 23:11:0711713 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0411714
11715 // Start the first transaction to set up the SpdySession
11716 HttpRequestInfo request1;
11717 request1.method = "GET";
11718 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0411719 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011720 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0411721 TestCompletionCallback callback1;
11722 EXPECT_EQ(ERR_IO_PENDING,
11723 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411724 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411725
11726 EXPECT_EQ(OK, callback1.WaitForResult());
11727 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
11728
11729 // Now, start the HTTP request
11730 HttpRequestInfo request2;
11731 request2.method = "GET";
11732 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0411733 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011734 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0411735 TestCompletionCallback callback2;
11736 EXPECT_EQ(ERR_IO_PENDING,
11737 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3411738 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0411739
11740 EXPECT_EQ(OK, callback2.WaitForResult());
11741 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11742}
11743
bnc1b0e36852015-04-28 15:32:5911744class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
11745 public:
11746 void Run(bool pooling, bool valid) {
11747 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
11748 443);
11749 HostPortPair alternative("www.example.org", 443);
11750
11751 base::FilePath certs_dir = GetTestCertsDirectory();
11752 scoped_refptr<X509Certificate> cert(
11753 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
11754 ASSERT_TRUE(cert.get());
11755 bool common_name_fallback_used;
11756 EXPECT_EQ(valid,
11757 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
11758 EXPECT_TRUE(
11759 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
11760 SSLSocketDataProvider ssl(ASYNC, OK);
11761 ssl.SetNextProto(GetParam());
11762 ssl.cert = cert;
11763 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11764
11765 // If pooling, then start a request to alternative first to create a
11766 // SpdySession.
11767 std::string url0 = "https://www.example.org:443";
11768 // Second request to origin, which has an alternative service, and could
11769 // open a connection to the alternative host or pool to the existing one.
11770 std::string url1("https://");
11771 url1.append(origin.host());
11772 url1.append(":443");
11773
11774 scoped_ptr<SpdyFrame> req0;
11775 scoped_ptr<SpdyFrame> req1;
11776 scoped_ptr<SpdyFrame> resp0;
11777 scoped_ptr<SpdyFrame> body0;
11778 scoped_ptr<SpdyFrame> resp1;
11779 scoped_ptr<SpdyFrame> body1;
11780 std::vector<MockWrite> writes;
11781 std::vector<MockRead> reads;
11782
11783 if (pooling) {
11784 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
11785 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
11786
11787 writes.push_back(CreateMockWrite(*req0, 0));
11788 writes.push_back(CreateMockWrite(*req1, 3));
11789
11790 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11791 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11792 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11793 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
11794
11795 reads.push_back(CreateMockRead(*resp0, 1));
11796 reads.push_back(CreateMockRead(*body0, 2));
11797 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
11798 reads.push_back(CreateMockRead(*resp1, 5));
11799 reads.push_back(CreateMockRead(*body1, 6));
11800 reads.push_back(MockRead(ASYNC, OK, 7));
11801 } else {
11802 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
11803
11804 writes.push_back(CreateMockWrite(*req1, 0));
11805
11806 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11807 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
11808
11809 reads.push_back(CreateMockRead(*resp1, 1));
11810 reads.push_back(CreateMockRead(*body1, 2));
11811 reads.push_back(MockRead(ASYNC, OK, 3));
11812 }
11813
rch32320842015-05-16 15:57:0911814 SequencedSocketData data(vector_as_array(&reads), reads.size(),
11815 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5911816 session_deps_.socket_factory->AddSocketDataProvider(&data);
11817
11818 // Connection to the origin fails.
11819 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11820 StaticSocketDataProvider data_refused;
11821 data_refused.set_connect_data(mock_connect);
11822 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11823
11824 session_deps_.use_alternate_protocols = true;
11825 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11826 base::WeakPtr<HttpServerProperties> http_server_properties =
11827 session->http_server_properties();
11828 AlternativeService alternative_service(
11829 AlternateProtocolFromNextProto(GetParam()), alternative);
11830 http_server_properties->SetAlternativeService(origin, alternative_service,
11831 1.0);
11832
11833 // First request to alternative.
11834 if (pooling) {
11835 scoped_ptr<HttpTransaction> trans0(
11836 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11837 HttpRequestInfo request0;
11838 request0.method = "GET";
11839 request0.url = GURL(url0);
11840 request0.load_flags = 0;
11841 TestCompletionCallback callback0;
11842
11843 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
11844 EXPECT_EQ(ERR_IO_PENDING, rv);
11845 rv = callback0.WaitForResult();
11846 EXPECT_EQ(OK, rv);
11847 }
11848
11849 // Second request to origin.
11850 scoped_ptr<HttpTransaction> trans1(
11851 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11852 HttpRequestInfo request1;
11853 request1.method = "GET";
11854 request1.url = GURL(url1);
11855 request1.load_flags = 0;
11856 TestCompletionCallback callback1;
11857
11858 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
11859 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0911860 base::MessageLoop::current()->RunUntilIdle();
11861 if (data.IsReadPaused()) {
11862 data.CompleteRead();
11863 }
bnc1b0e36852015-04-28 15:32:5911864 rv = callback1.WaitForResult();
11865 if (valid) {
11866 EXPECT_EQ(OK, rv);
11867 } else {
11868 if (pooling) {
11869 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11870 } else {
11871 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
11872 }
11873 }
11874 }
11875};
11876
11877INSTANTIATE_TEST_CASE_P(NextProto,
11878 AltSvcCertificateVerificationTest,
11879 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:4311880 kProtoHTTP2_14,
11881 kProtoHTTP2));
bnc1b0e36852015-04-28 15:32:5911882
11883// The alternative service host must exhibit a certificate that is valid for the
11884// origin host. Test that this is enforced when pooling to an existing
11885// connection.
11886TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
11887 Run(true, true);
11888}
11889
11890TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
11891 Run(true, false);
11892}
11893
11894// The alternative service host must exhibit a certificate that is valid for the
11895// origin host. Test that this is enforced when opening a new connection.
11896TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
11897 Run(false, true);
11898}
11899
11900TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
11901 Run(false, false);
11902}
11903
bnc5452e2a2015-05-08 16:27:4211904// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
11905// with the alternative server. That connection should not be used.
11906TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
11907 HostPortPair origin("origin.example.org", 443);
11908 HostPortPair alternative("alternative.example.org", 443);
11909
11910 // Negotiate HTTP/1.1 with alternative.example.org.
11911 SSLSocketDataProvider ssl(ASYNC, OK);
11912 ssl.SetNextProto(kProtoHTTP11);
11913 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11914
11915 // No data should be read from the alternative, because HTTP/1.1 is
11916 // negotiated.
11917 StaticSocketDataProvider data;
11918 session_deps_.socket_factory->AddSocketDataProvider(&data);
11919
11920 // This test documents that an alternate Job should not be used if HTTP/1.1 is
11921 // negotiated. In order to test this, a failed connection to the origin is
11922 // mocked. This way the request relies on the alternate Job.
11923 StaticSocketDataProvider data_refused;
11924 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11925 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11926
11927 // Set up alternative service for origin.
11928 session_deps_.use_alternate_protocols = true;
11929 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11930 base::WeakPtr<HttpServerProperties> http_server_properties =
11931 session->http_server_properties();
11932 AlternativeService alternative_service(
11933 AlternateProtocolFromNextProto(GetParam()), alternative);
11934 http_server_properties->SetAlternativeService(origin, alternative_service,
11935 1.0);
11936
11937 scoped_ptr<HttpTransaction> trans(
11938 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11939 HttpRequestInfo request;
11940 request.method = "GET";
11941 request.url = GURL("https://origin.example.org:443");
11942 request.load_flags = 0;
11943 TestCompletionCallback callback;
11944
11945 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
11946 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
11947 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11948 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
11949}
11950
bnc40448a532015-05-11 19:13:1411951// A request to a server with an alternative service fires two Jobs: one to the
11952// origin, and an alternate one to the alternative server. If the former
11953// succeeds, the request should succeed, even if the latter fails because
11954// HTTP/1.1 is negotiated which is insufficient for alternative service.
11955TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
11956 HostPortPair origin("origin.example.org", 443);
11957 HostPortPair alternative("alternative.example.org", 443);
11958
11959 // Negotiate HTTP/1.1 with alternative.
11960 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
11961 alternative_ssl.SetNextProto(kProtoHTTP11);
11962 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
11963
11964 // No data should be read from the alternative, because HTTP/1.1 is
11965 // negotiated.
11966 StaticSocketDataProvider data;
11967 session_deps_.socket_factory->AddSocketDataProvider(&data);
11968
11969 // Negotiate HTTP/1.1 with origin.
11970 SSLSocketDataProvider origin_ssl(ASYNC, OK);
11971 origin_ssl.SetNextProto(kProtoHTTP11);
11972 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
11973
11974 MockWrite http_writes[] = {
11975 MockWrite(
11976 "GET / HTTP/1.1\r\n"
11977 "Host: origin.example.org\r\n"
11978 "Connection: keep-alive\r\n\r\n"),
11979 MockWrite(
11980 "GET /second HTTP/1.1\r\n"
11981 "Host: origin.example.org\r\n"
11982 "Connection: keep-alive\r\n\r\n"),
11983 };
11984
11985 MockRead http_reads[] = {
11986 MockRead("HTTP/1.1 200 OK\r\n"),
11987 MockRead("Content-Type: text/html\r\n"),
11988 MockRead("Content-Length: 6\r\n\r\n"),
11989 MockRead("foobar"),
11990 MockRead("HTTP/1.1 200 OK\r\n"),
11991 MockRead("Content-Type: text/html\r\n"),
11992 MockRead("Content-Length: 7\r\n\r\n"),
11993 MockRead("another"),
11994 };
11995 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
11996 http_writes, arraysize(http_writes));
11997 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11998
11999 // Set up alternative service for origin.
12000 session_deps_.use_alternate_protocols = true;
12001 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12002 base::WeakPtr<HttpServerProperties> http_server_properties =
12003 session->http_server_properties();
12004 AlternativeService alternative_service(
12005 AlternateProtocolFromNextProto(GetParam()), alternative);
12006 http_server_properties->SetAlternativeService(origin, alternative_service,
12007 1.0);
12008
12009 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
12010 HttpRequestInfo request1;
12011 request1.method = "GET";
12012 request1.url = GURL("https://origin.example.org:443");
12013 request1.load_flags = 0;
12014 TestCompletionCallback callback1;
12015
12016 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
12017 rv = callback1.GetResult(rv);
12018 EXPECT_EQ(OK, rv);
12019
12020 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
12021 ASSERT_TRUE(response1 != nullptr);
12022 ASSERT_TRUE(response1->headers.get() != nullptr);
12023 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12024
12025 std::string response_data1;
12026 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
12027 EXPECT_EQ("foobar", response_data1);
12028
12029 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
12030 // for alternative service.
12031 EXPECT_TRUE(
12032 http_server_properties->IsAlternativeServiceBroken(alternative_service));
12033
12034 // Since |alternative_service| is broken, a second transaction to origin
12035 // should not start an alternate Job. It should pool to existing connection
12036 // to origin.
12037 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
12038 HttpRequestInfo request2;
12039 request2.method = "GET";
12040 request2.url = GURL("https://origin.example.org:443/second");
12041 request2.load_flags = 0;
12042 TestCompletionCallback callback2;
12043
12044 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
12045 rv = callback2.GetResult(rv);
12046 EXPECT_EQ(OK, rv);
12047
12048 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
12049 ASSERT_TRUE(response2 != nullptr);
12050 ASSERT_TRUE(response2->headers.get() != nullptr);
12051 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
12052
12053 std::string response_data2;
12054 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
12055 EXPECT_EQ("another", response_data2);
12056}
12057
bnc5452e2a2015-05-08 16:27:4212058// Alternative service requires HTTP/2 (or SPDY), but there is already a
12059// HTTP/1.1 socket open to the alternative server. That socket should not be
12060// used.
12061TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12062 HostPortPair origin("origin.example.org", 443);
12063 HostPortPair alternative("alternative.example.org", 443);
12064 std::string origin_url = "https://origin.example.org:443";
12065 std::string alternative_url = "https://alternative.example.org:443";
12066
12067 // Negotiate HTTP/1.1 with alternative.example.org.
12068 SSLSocketDataProvider ssl(ASYNC, OK);
12069 ssl.SetNextProto(kProtoHTTP11);
12070 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12071
12072 // HTTP/1.1 data for |request1| and |request2|.
12073 MockWrite http_writes[] = {
12074 MockWrite(
12075 "GET / HTTP/1.1\r\n"
12076 "Host: alternative.example.org\r\n"
12077 "Connection: keep-alive\r\n\r\n"),
12078 MockWrite(
12079 "GET / HTTP/1.1\r\n"
12080 "Host: alternative.example.org\r\n"
12081 "Connection: keep-alive\r\n\r\n"),
12082 };
12083
12084 MockRead http_reads[] = {
12085 MockRead(
12086 "HTTP/1.1 200 OK\r\n"
12087 "Content-Type: text/html; charset=iso-8859-1\r\n"
12088 "Content-Length: 40\r\n\r\n"
12089 "first HTTP/1.1 response from alternative"),
12090 MockRead(
12091 "HTTP/1.1 200 OK\r\n"
12092 "Content-Type: text/html; charset=iso-8859-1\r\n"
12093 "Content-Length: 41\r\n\r\n"
12094 "second HTTP/1.1 response from alternative"),
12095 };
12096 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12097 http_writes, arraysize(http_writes));
12098 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12099
12100 // This test documents that an alternate Job should not pool to an already
12101 // existing HTTP/1.1 connection. In order to test this, a failed connection
12102 // to the origin is mocked. This way |request2| relies on the alternate Job.
12103 StaticSocketDataProvider data_refused;
12104 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12105 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12106
12107 // Set up alternative service for origin.
12108 session_deps_.use_alternate_protocols = true;
12109 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12110 base::WeakPtr<HttpServerProperties> http_server_properties =
12111 session->http_server_properties();
12112 AlternativeService alternative_service(
12113 AlternateProtocolFromNextProto(GetParam()), alternative);
12114 http_server_properties->SetAlternativeService(origin, alternative_service,
12115 1.0);
12116
12117 // First transaction to alternative to open an HTTP/1.1 socket.
12118 scoped_ptr<HttpTransaction> trans1(
12119 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12120 HttpRequestInfo request1;
12121 request1.method = "GET";
12122 request1.url = GURL(alternative_url);
12123 request1.load_flags = 0;
12124 TestCompletionCallback callback1;
12125
12126 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12127 EXPECT_EQ(OK, callback1.GetResult(rv));
12128 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12129 ASSERT_TRUE(response1);
12130 ASSERT_TRUE(response1->headers.get());
12131 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12132 EXPECT_TRUE(response1->was_npn_negotiated);
12133 EXPECT_FALSE(response1->was_fetched_via_spdy);
12134 std::string response_data1;
12135 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12136 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12137
12138 // Request for origin.example.org, which has an alternative service. This
12139 // will start two Jobs: the alternative looks for connections to pool to,
12140 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12141 // open other connections to alternative server. The Job to origin fails, so
12142 // this request fails.
12143 scoped_ptr<HttpTransaction> trans2(
12144 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12145 HttpRequestInfo request2;
12146 request2.method = "GET";
12147 request2.url = GURL(origin_url);
12148 request2.load_flags = 0;
12149 TestCompletionCallback callback2;
12150
12151 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12152 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12153
12154 // Another transaction to alternative. This is to test that the HTTP/1.1
12155 // socket is still open and in the pool.
12156 scoped_ptr<HttpTransaction> trans3(
12157 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12158 HttpRequestInfo request3;
12159 request3.method = "GET";
12160 request3.url = GURL(alternative_url);
12161 request3.load_flags = 0;
12162 TestCompletionCallback callback3;
12163
12164 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12165 EXPECT_EQ(OK, callback3.GetResult(rv));
12166 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12167 ASSERT_TRUE(response3);
12168 ASSERT_TRUE(response3->headers.get());
12169 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12170 EXPECT_TRUE(response3->was_npn_negotiated);
12171 EXPECT_FALSE(response3->was_fetched_via_spdy);
12172 std::string response_data3;
12173 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12174 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12175}
12176
[email protected]23e482282013-06-14 16:08:0212177TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2312178 const std::string https_url = "https://www.example.org:8080/";
12179 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412180
12181 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2312182 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3412183 scoped_ptr<SpdyFrame> connect(
12184 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4612185 scoped_ptr<SpdyFrame> req1(
12186 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0212187 scoped_ptr<SpdyFrame> wrapped_req1(
12188 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3912189
12190 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2912191 SpdyHeaderBlock req2_block;
12192 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3812193 req2_block[spdy_util_.GetPathKey()] = "/";
bncce36dca22015-04-21 22:11:2312194 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2912195 req2_block[spdy_util_.GetSchemeKey()] = "http";
12196 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3912197 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2912198 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0412199
12200 MockWrite writes1[] = {
12201 CreateMockWrite(*connect, 0),
12202 CreateMockWrite(*wrapped_req1, 2),
12203 CreateMockWrite(*req2, 5),
12204 };
12205
[email protected]23e482282013-06-14 16:08:0212206 scoped_ptr<SpdyFrame> conn_resp(
12207 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12208 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12209 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12210 scoped_ptr<SpdyFrame> wrapped_resp1(
12211 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12212 scoped_ptr<SpdyFrame> wrapped_body1(
12213 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12214 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12215 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412216 MockRead reads1[] = {
12217 CreateMockRead(*conn_resp, 1),
12218 CreateMockRead(*wrapped_resp1, 3),
12219 CreateMockRead(*wrapped_body1, 4),
12220 CreateMockRead(*resp2, 6),
12221 CreateMockRead(*body2, 7),
12222 MockRead(ASYNC, ERR_IO_PENDING, 8)
12223 };
12224
[email protected]dd54bd82012-07-19 23:44:5712225 DeterministicSocketData data1(reads1, arraysize(reads1),
12226 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412227 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712228 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412229
[email protected]bb88e1d32013-05-03 23:11:0712230 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2212231 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:5112232 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712233 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412234 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212235 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712236 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412237 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212238 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712239 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12240 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412241
12242 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712243 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412244
12245 // Start the first transaction to set up the SpdySession
12246 HttpRequestInfo request1;
12247 request1.method = "GET";
12248 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412249 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012250 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412251 TestCompletionCallback callback1;
12252 EXPECT_EQ(ERR_IO_PENDING,
12253 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412254 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712255 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412256
12257 EXPECT_EQ(OK, callback1.WaitForResult());
12258 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12259
[email protected]f6c63db52013-02-02 00:35:2212260 LoadTimingInfo load_timing_info1;
12261 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12262 TestLoadTimingNotReusedWithPac(load_timing_info1,
12263 CONNECT_TIMING_HAS_SSL_TIMES);
12264
[email protected]8450d722012-07-02 19:14:0412265 // Now, start the HTTP request
12266 HttpRequestInfo request2;
12267 request2.method = "GET";
12268 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412269 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012270 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412271 TestCompletionCallback callback2;
12272 EXPECT_EQ(ERR_IO_PENDING,
12273 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412274 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712275 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412276
12277 EXPECT_EQ(OK, callback2.WaitForResult());
12278 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212279
12280 LoadTimingInfo load_timing_info2;
12281 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12282 // The established SPDY sessions is considered reused by the HTTP request.
12283 TestLoadTimingReusedWithPac(load_timing_info2);
12284 // HTTP requests over a SPDY session should have a different connection
12285 // socket_log_id than requests over a tunnel.
12286 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412287}
12288
[email protected]2d88e7d2012-07-19 17:55:1712289// Test that in the case where we have a SPDY session to a SPDY proxy
12290// that we do not pool other origins that resolve to the same IP when
12291// the certificate does not match the new origin.
12292// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212293TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312294 const std::string url1 = "http://www.example.org/";
12295 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712296 const std::string ip_addr = "1.2.3.4";
12297
12298 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212299 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312300 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912301 scoped_ptr<SpdyFrame> req1(
12302 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712303
12304 MockWrite writes1[] = {
12305 CreateMockWrite(*req1, 0),
12306 };
12307
[email protected]23e482282013-06-14 16:08:0212308 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12309 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712310 MockRead reads1[] = {
12311 CreateMockRead(*resp1, 1),
12312 CreateMockRead(*body1, 2),
12313 MockRead(ASYNC, OK, 3) // EOF
12314 };
12315
12316 scoped_ptr<DeterministicSocketData> data1(
12317 new DeterministicSocketData(reads1, arraysize(reads1),
12318 writes1, arraysize(writes1)));
12319 IPAddressNumber ip;
12320 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12321 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12322 MockConnect connect_data1(ASYNC, OK, peer_addr);
12323 data1->set_connect_data(connect_data1);
12324
12325 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612326 scoped_ptr<SpdyFrame> req2(
12327 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712328
12329 MockWrite writes2[] = {
12330 CreateMockWrite(*req2, 0),
12331 };
12332
[email protected]23e482282013-06-14 16:08:0212333 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12334 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712335 MockRead reads2[] = {
12336 CreateMockRead(*resp2, 1),
12337 CreateMockRead(*body2, 2),
12338 MockRead(ASYNC, OK, 3) // EOF
12339 };
12340
12341 scoped_ptr<DeterministicSocketData> data2(
12342 new DeterministicSocketData(reads2, arraysize(reads2),
12343 writes2, arraysize(writes2)));
12344 MockConnect connect_data2(ASYNC, OK);
12345 data2->set_connect_data(connect_data2);
12346
12347 // Set up a proxy config that sends HTTP requests to a proxy, and
12348 // all others direct.
12349 ProxyConfig proxy_config;
12350 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712351 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:1312352 new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
[email protected]2d88e7d2012-07-19 17:55:1712353
bncce36dca22015-04-21 22:11:2312354 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12355 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712356 // Load a valid cert. Note, that this does not need to
12357 // be valid for proxy because the MockSSLClientSocket does
12358 // not actually verify it. But SpdySession will use this
12359 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312360 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12361 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712362 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12363 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12364 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712365
12366 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212367 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712368 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12369 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12370 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712371
[email protected]bb88e1d32013-05-03 23:11:0712372 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312373 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712374 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712375
12376 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712377 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712378
12379 // Start the first transaction to set up the SpdySession
12380 HttpRequestInfo request1;
12381 request1.method = "GET";
12382 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712383 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012384 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712385 TestCompletionCallback callback1;
12386 ASSERT_EQ(ERR_IO_PENDING,
12387 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12388 data1->RunFor(3);
12389
12390 ASSERT_TRUE(callback1.have_result());
12391 EXPECT_EQ(OK, callback1.WaitForResult());
12392 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12393
12394 // Now, start the HTTP request
12395 HttpRequestInfo request2;
12396 request2.method = "GET";
12397 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712398 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012399 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712400 TestCompletionCallback callback2;
12401 EXPECT_EQ(ERR_IO_PENDING,
12402 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412403 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712404 data2->RunFor(3);
12405
12406 ASSERT_TRUE(callback2.have_result());
12407 EXPECT_EQ(OK, callback2.WaitForResult());
12408 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12409}
12410
[email protected]85f97342013-04-17 06:12:2412411// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12412// error) in SPDY session, removes the socket from pool and closes the SPDY
12413// session. Verify that new url's from the same HttpNetworkSession (and a new
12414// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212415TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312416 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412417
12418 MockRead reads1[] = {
12419 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12420 };
12421
mmenke11eb5152015-06-09 14:50:5012422 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2412423
[email protected]cdf8f7e72013-05-23 10:56:4612424 scoped_ptr<SpdyFrame> req2(
12425 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412426 MockWrite writes2[] = {
12427 CreateMockWrite(*req2, 0),
12428 };
12429
[email protected]23e482282013-06-14 16:08:0212430 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12431 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412432 MockRead reads2[] = {
12433 CreateMockRead(*resp2, 1),
12434 CreateMockRead(*body2, 2),
12435 MockRead(ASYNC, OK, 3) // EOF
12436 };
12437
mmenke11eb5152015-06-09 14:50:5012438 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12439 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2412440
[email protected]85f97342013-04-17 06:12:2412441 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212442 ssl1.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012443 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12444 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2412445
12446 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212447 ssl2.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12449 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2412450
12451 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5012452 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412453
12454 // Start the first transaction to set up the SpdySession and verify that
12455 // connection was closed.
12456 HttpRequestInfo request1;
12457 request1.method = "GET";
12458 request1.url = GURL(https_url);
12459 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012460 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412461 TestCompletionCallback callback1;
12462 EXPECT_EQ(ERR_IO_PENDING,
12463 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412464 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12465
12466 // Now, start the second request and make sure it succeeds.
12467 HttpRequestInfo request2;
12468 request2.method = "GET";
12469 request2.url = GURL(https_url);
12470 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012471 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412472 TestCompletionCallback callback2;
12473 EXPECT_EQ(ERR_IO_PENDING,
12474 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412475
mmenke11eb5152015-06-09 14:50:5012476 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2412477 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12478}
12479
[email protected]23e482282013-06-14 16:08:0212480TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312481 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312482 ClientSocketPoolManager::set_max_sockets_per_group(
12483 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12484 ClientSocketPoolManager::set_max_sockets_per_pool(
12485 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12486
12487 // Use two different hosts with different IPs so they don't get pooled.
12488 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12489 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
12490 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12491
12492 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212493 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312494 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212495 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312496 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12497 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12498
[email protected]cdf8f7e72013-05-23 10:56:4612499 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312500 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12501 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1312502 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0312503 };
[email protected]23e482282013-06-14 16:08:0212504 scoped_ptr<SpdyFrame> host1_resp(
12505 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12506 scoped_ptr<SpdyFrame> host1_resp_body(
12507 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312508 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1312509 CreateMockRead(*host1_resp, 1),
12510 CreateMockRead(*host1_resp_body, 2),
12511 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312512 };
12513
rch8e6c6c42015-05-01 14:05:1312514 scoped_ptr<SequencedSocketData> spdy1_data(
12515 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
12516 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0312517 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12518
[email protected]cdf8f7e72013-05-23 10:56:4612519 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312520 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12521 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1312522 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0312523 };
[email protected]23e482282013-06-14 16:08:0212524 scoped_ptr<SpdyFrame> host2_resp(
12525 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12526 scoped_ptr<SpdyFrame> host2_resp_body(
12527 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312528 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1312529 CreateMockRead(*host2_resp, 1),
12530 CreateMockRead(*host2_resp_body, 2),
12531 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312532 };
12533
rch8e6c6c42015-05-01 14:05:1312534 scoped_ptr<SequencedSocketData> spdy2_data(
12535 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
12536 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0312537 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12538
12539 MockWrite http_write[] = {
12540 MockWrite("GET / HTTP/1.1\r\n"
12541 "Host: www.a.com\r\n"
12542 "Connection: keep-alive\r\n\r\n"),
12543 };
12544
12545 MockRead http_read[] = {
12546 MockRead("HTTP/1.1 200 OK\r\n"),
12547 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12548 MockRead("Content-Length: 6\r\n\r\n"),
12549 MockRead("hello!"),
12550 };
12551 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12552 http_write, arraysize(http_write));
12553 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12554
12555 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012556 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312557 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312558 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612559 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312560
12561 TestCompletionCallback callback;
12562 HttpRequestInfo request1;
12563 request1.method = "GET";
12564 request1.url = GURL("https://www.a.com/");
12565 request1.load_flags = 0;
12566 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012567 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312568
12569 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
12570 EXPECT_EQ(ERR_IO_PENDING, rv);
12571 EXPECT_EQ(OK, callback.WaitForResult());
12572
12573 const HttpResponseInfo* response = trans->GetResponseInfo();
12574 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012575 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312576 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12577 EXPECT_TRUE(response->was_fetched_via_spdy);
12578 EXPECT_TRUE(response->was_npn_negotiated);
12579
12580 std::string response_data;
12581 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12582 EXPECT_EQ("hello!", response_data);
12583 trans.reset();
12584 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612585 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312586
12587 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4012588 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5312589 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312590 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612591 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312592 HttpRequestInfo request2;
12593 request2.method = "GET";
12594 request2.url = GURL("https://www.b.com/");
12595 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012596 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312597
12598 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
12599 EXPECT_EQ(ERR_IO_PENDING, rv);
12600 EXPECT_EQ(OK, callback.WaitForResult());
12601
12602 response = trans->GetResponseInfo();
12603 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012604 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312605 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12606 EXPECT_TRUE(response->was_fetched_via_spdy);
12607 EXPECT_TRUE(response->was_npn_negotiated);
12608 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12609 EXPECT_EQ("hello!", response_data);
12610 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612611 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312612 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612613 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312614
12615 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4012616 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5312617 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312618 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612619 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0312620 HttpRequestInfo request3;
12621 request3.method = "GET";
12622 request3.url = GURL("http://www.a.com/");
12623 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012624 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312625
12626 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
12627 EXPECT_EQ(ERR_IO_PENDING, rv);
12628 EXPECT_EQ(OK, callback.WaitForResult());
12629
12630 response = trans->GetResponseInfo();
12631 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012632 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312633 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12634 EXPECT_FALSE(response->was_fetched_via_spdy);
12635 EXPECT_FALSE(response->was_npn_negotiated);
12636 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12637 EXPECT_EQ("hello!", response_data);
12638 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612639 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312640 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612641 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0312642}
12643
[email protected]79e1fd62013-06-20 06:50:0412644TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
12645 HttpRequestInfo request;
12646 request.method = "GET";
bncce36dca22015-04-21 22:11:2312647 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412648 request.load_flags = 0;
12649
[email protected]3fe8d2f82013-10-17 08:56:0712650 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412651 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112652 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412653
12654 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
12655 StaticSocketDataProvider data;
12656 data.set_connect_data(mock_connect);
12657 session_deps_.socket_factory->AddSocketDataProvider(&data);
12658
12659 TestCompletionCallback callback;
12660
12661 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12662 EXPECT_EQ(ERR_IO_PENDING, rv);
12663
12664 rv = callback.WaitForResult();
12665 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12666
[email protected]79e1fd62013-06-20 06:50:0412667 // We don't care whether this succeeds or fails, but it shouldn't crash.
12668 HttpRequestHeaders request_headers;
12669 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712670
12671 ConnectionAttempts attempts;
12672 trans->GetConnectionAttempts(&attempts);
12673 ASSERT_EQ(1u, attempts.size());
12674 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412675}
12676
12677TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
12678 HttpRequestInfo request;
12679 request.method = "GET";
bncce36dca22015-04-21 22:11:2312680 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412681 request.load_flags = 0;
12682
[email protected]3fe8d2f82013-10-17 08:56:0712683 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412684 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112685 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412686
12687 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12688 StaticSocketDataProvider data;
12689 data.set_connect_data(mock_connect);
12690 session_deps_.socket_factory->AddSocketDataProvider(&data);
12691
12692 TestCompletionCallback callback;
12693
12694 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12695 EXPECT_EQ(ERR_IO_PENDING, rv);
12696
12697 rv = callback.WaitForResult();
12698 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12699
[email protected]79e1fd62013-06-20 06:50:0412700 // We don't care whether this succeeds or fails, but it shouldn't crash.
12701 HttpRequestHeaders request_headers;
12702 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4712703
12704 ConnectionAttempts attempts;
12705 trans->GetConnectionAttempts(&attempts);
12706 ASSERT_EQ(1u, attempts.size());
12707 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0412708}
12709
12710TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12711 HttpRequestInfo request;
12712 request.method = "GET";
bncce36dca22015-04-21 22:11:2312713 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412714 request.load_flags = 0;
12715
[email protected]3fe8d2f82013-10-17 08:56:0712716 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412717 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112718 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412719
12720 MockWrite data_writes[] = {
12721 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12722 };
12723 MockRead data_reads[] = {
12724 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12725 };
12726
12727 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12728 data_writes, arraysize(data_writes));
12729 session_deps_.socket_factory->AddSocketDataProvider(&data);
12730
12731 TestCompletionCallback callback;
12732
12733 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12734 EXPECT_EQ(ERR_IO_PENDING, rv);
12735
12736 rv = callback.WaitForResult();
12737 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12738
[email protected]79e1fd62013-06-20 06:50:0412739 HttpRequestHeaders request_headers;
12740 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12741 EXPECT_TRUE(request_headers.HasHeader("Host"));
12742}
12743
12744TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12745 HttpRequestInfo request;
12746 request.method = "GET";
bncce36dca22015-04-21 22:11:2312747 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412748 request.load_flags = 0;
12749
[email protected]3fe8d2f82013-10-17 08:56:0712750 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412751 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112752 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412753
12754 MockWrite data_writes[] = {
12755 MockWrite(ASYNC, ERR_CONNECTION_RESET),
12756 };
12757 MockRead data_reads[] = {
12758 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
12759 };
12760
12761 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12762 data_writes, arraysize(data_writes));
12763 session_deps_.socket_factory->AddSocketDataProvider(&data);
12764
12765 TestCompletionCallback callback;
12766
12767 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12768 EXPECT_EQ(ERR_IO_PENDING, rv);
12769
12770 rv = callback.WaitForResult();
12771 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12772
[email protected]79e1fd62013-06-20 06:50:0412773 HttpRequestHeaders request_headers;
12774 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12775 EXPECT_TRUE(request_headers.HasHeader("Host"));
12776}
12777
12778TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12779 HttpRequestInfo request;
12780 request.method = "GET";
bncce36dca22015-04-21 22:11:2312781 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412782 request.load_flags = 0;
12783
[email protected]3fe8d2f82013-10-17 08:56:0712784 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412785 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112786 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412787
12788 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312789 MockWrite(
12790 "GET / HTTP/1.1\r\n"
12791 "Host: www.example.org\r\n"
12792 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412793 };
12794 MockRead data_reads[] = {
12795 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12796 };
12797
12798 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12799 data_writes, arraysize(data_writes));
12800 session_deps_.socket_factory->AddSocketDataProvider(&data);
12801
12802 TestCompletionCallback callback;
12803
12804 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12805 EXPECT_EQ(ERR_IO_PENDING, rv);
12806
12807 rv = callback.WaitForResult();
12808 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12809
[email protected]79e1fd62013-06-20 06:50:0412810 HttpRequestHeaders request_headers;
12811 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12812 EXPECT_TRUE(request_headers.HasHeader("Host"));
12813}
12814
12815TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12816 HttpRequestInfo request;
12817 request.method = "GET";
bncce36dca22015-04-21 22:11:2312818 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412819 request.load_flags = 0;
12820
[email protected]3fe8d2f82013-10-17 08:56:0712821 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412822 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112823 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412824
12825 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312826 MockWrite(
12827 "GET / HTTP/1.1\r\n"
12828 "Host: www.example.org\r\n"
12829 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412830 };
12831 MockRead data_reads[] = {
12832 MockRead(ASYNC, ERR_CONNECTION_RESET),
12833 };
12834
12835 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12836 data_writes, arraysize(data_writes));
12837 session_deps_.socket_factory->AddSocketDataProvider(&data);
12838
12839 TestCompletionCallback callback;
12840
12841 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12842 EXPECT_EQ(ERR_IO_PENDING, rv);
12843
12844 rv = callback.WaitForResult();
12845 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12846
[email protected]79e1fd62013-06-20 06:50:0412847 HttpRequestHeaders request_headers;
12848 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12849 EXPECT_TRUE(request_headers.HasHeader("Host"));
12850}
12851
12852TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12853 HttpRequestInfo request;
12854 request.method = "GET";
bncce36dca22015-04-21 22:11:2312855 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0412856 request.load_flags = 0;
12857 request.extra_headers.SetHeader("X-Foo", "bar");
12858
[email protected]3fe8d2f82013-10-17 08:56:0712859 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0412860 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112861 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0412862
12863 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312864 MockWrite(
12865 "GET / HTTP/1.1\r\n"
12866 "Host: www.example.org\r\n"
12867 "Connection: keep-alive\r\n"
12868 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0412869 };
12870 MockRead data_reads[] = {
12871 MockRead("HTTP/1.1 200 OK\r\n"
12872 "Content-Length: 5\r\n\r\n"
12873 "hello"),
12874 MockRead(ASYNC, ERR_UNEXPECTED),
12875 };
12876
12877 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12878 data_writes, arraysize(data_writes));
12879 session_deps_.socket_factory->AddSocketDataProvider(&data);
12880
12881 TestCompletionCallback callback;
12882
12883 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12884 EXPECT_EQ(ERR_IO_PENDING, rv);
12885
12886 rv = callback.WaitForResult();
12887 EXPECT_EQ(OK, rv);
12888
12889 HttpRequestHeaders request_headers;
12890 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12891 std::string foo;
12892 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12893 EXPECT_EQ("bar", foo);
12894}
12895
[email protected]bf828982013-08-14 18:01:4712896namespace {
12897
yhiranoa7e05bb2014-11-06 05:40:3912898// Fake HttpStream that simply records calls to SetPriority().
12899class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0312900 public base::SupportsWeakPtr<FakeStream> {
12901 public:
12902 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2012903 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0312904
12905 RequestPriority priority() const { return priority_; }
12906
dchengb03027d2014-10-21 12:00:2012907 int InitializeStream(const HttpRequestInfo* request_info,
12908 RequestPriority priority,
12909 const BoundNetLog& net_log,
12910 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312911 return ERR_IO_PENDING;
12912 }
12913
dchengb03027d2014-10-21 12:00:2012914 int SendRequest(const HttpRequestHeaders& request_headers,
12915 HttpResponseInfo* response,
12916 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312917 ADD_FAILURE();
12918 return ERR_UNEXPECTED;
12919 }
12920
dchengb03027d2014-10-21 12:00:2012921 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312922 ADD_FAILURE();
12923 return ERR_UNEXPECTED;
12924 }
12925
dchengb03027d2014-10-21 12:00:2012926 int ReadResponseBody(IOBuffer* buf,
12927 int buf_len,
12928 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0312929 ADD_FAILURE();
12930 return ERR_UNEXPECTED;
12931 }
12932
dchengb03027d2014-10-21 12:00:2012933 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0312934
dchengb03027d2014-10-21 12:00:2012935 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0312936 ADD_FAILURE();
12937 return false;
12938 }
12939
dchengb03027d2014-10-21 12:00:2012940 bool CanFindEndOfResponse() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0312941
dchengb03027d2014-10-21 12:00:2012942 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0312943 ADD_FAILURE();
12944 return false;
12945 }
12946
dchengb03027d2014-10-21 12:00:2012947 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312948
dchengb03027d2014-10-21 12:00:2012949 bool IsConnectionReusable() const override {
[email protected]e86839fd2013-08-14 18:29:0312950 ADD_FAILURE();
12951 return false;
12952 }
12953
dchengb03027d2014-10-21 12:00:2012954 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5912955 ADD_FAILURE();
12956 return 0;
12957 }
12958
dchengb03027d2014-10-21 12:00:2012959 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0312960 ADD_FAILURE();
12961 return false;
12962 }
12963
dchengb03027d2014-10-21 12:00:2012964 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
12965
12966 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0312967 ADD_FAILURE();
12968 }
12969
dchengb03027d2014-10-21 12:00:2012970 bool IsSpdyHttpStream() const override {
[email protected]e86839fd2013-08-14 18:29:0312971 ADD_FAILURE();
12972 return false;
12973 }
12974
dchengb03027d2014-10-21 12:00:2012975 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0312976
dchengb03027d2014-10-21 12:00:2012977 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0312978
yhiranoa7e05bb2014-11-06 05:40:3912979 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
12980
12981 HttpStream* RenewStreamForAuth() override { return NULL; }
12982
[email protected]e86839fd2013-08-14 18:29:0312983 private:
12984 RequestPriority priority_;
12985
12986 DISALLOW_COPY_AND_ASSIGN(FakeStream);
12987};
12988
12989// Fake HttpStreamRequest that simply records calls to SetPriority()
12990// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4712991class FakeStreamRequest : public HttpStreamRequest,
12992 public base::SupportsWeakPtr<FakeStreamRequest> {
12993 public:
[email protected]e86839fd2013-08-14 18:29:0312994 FakeStreamRequest(RequestPriority priority,
12995 HttpStreamRequest::Delegate* delegate)
12996 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4412997 delegate_(delegate),
12998 websocket_stream_create_helper_(NULL) {}
12999
13000 FakeStreamRequest(RequestPriority priority,
13001 HttpStreamRequest::Delegate* delegate,
13002 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
13003 : priority_(priority),
13004 delegate_(delegate),
13005 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0313006
dchengb03027d2014-10-21 12:00:2013007 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4713008
13009 RequestPriority priority() const { return priority_; }
13010
[email protected]831e4a32013-11-14 02:14:4413011 const WebSocketHandshakeStreamBase::CreateHelper*
13012 websocket_stream_create_helper() const {
13013 return websocket_stream_create_helper_;
13014 }
13015
[email protected]e86839fd2013-08-14 18:29:0313016 // Create a new FakeStream and pass it to the request's
13017 // delegate. Returns a weak pointer to the FakeStream.
13018 base::WeakPtr<FakeStream> FinishStreamRequest() {
13019 FakeStream* fake_stream = new FakeStream(priority_);
13020 // Do this before calling OnStreamReady() as OnStreamReady() may
13021 // immediately delete |fake_stream|.
13022 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
13023 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
13024 return weak_stream;
13025 }
13026
dchengb03027d2014-10-21 12:00:2013027 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4713028 ADD_FAILURE();
13029 return ERR_UNEXPECTED;
13030 }
13031
dchengb03027d2014-10-21 12:00:2013032 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4713033 ADD_FAILURE();
13034 return LoadState();
13035 }
13036
dchengb03027d2014-10-21 12:00:2013037 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4713038
dchengb03027d2014-10-21 12:00:2013039 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713040
dchengb03027d2014-10-21 12:00:2013041 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4713042
dchengb03027d2014-10-21 12:00:2013043 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713044
ttuttle1f2d7e92015-04-28 16:17:4713045 const ConnectionAttempts& connection_attempts() const override {
13046 static ConnectionAttempts no_attempts;
13047 return no_attempts;
13048 }
13049
[email protected]bf828982013-08-14 18:01:4713050 private:
13051 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0313052 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4413053 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4713054
13055 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
13056};
13057
13058// Fake HttpStreamFactory that vends FakeStreamRequests.
13059class FakeStreamFactory : public HttpStreamFactory {
13060 public:
13061 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2013062 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4713063
13064 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
13065 // RequestStream() (which may be NULL if it was destroyed already).
13066 base::WeakPtr<FakeStreamRequest> last_stream_request() {
13067 return last_stream_request_;
13068 }
13069
dchengb03027d2014-10-21 12:00:2013070 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
13071 RequestPriority priority,
13072 const SSLConfig& server_ssl_config,
13073 const SSLConfig& proxy_ssl_config,
13074 HttpStreamRequest::Delegate* delegate,
13075 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0313076 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4713077 last_stream_request_ = fake_request->AsWeakPtr();
13078 return fake_request;
13079 }
13080
dchengb03027d2014-10-21 12:00:2013081 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4713082 const HttpRequestInfo& info,
13083 RequestPriority priority,
13084 const SSLConfig& server_ssl_config,
13085 const SSLConfig& proxy_ssl_config,
13086 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4613087 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1313088 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4413089 FakeStreamRequest* fake_request =
13090 new FakeStreamRequest(priority, delegate, create_helper);
13091 last_stream_request_ = fake_request->AsWeakPtr();
13092 return fake_request;
[email protected]bf828982013-08-14 18:01:4713093 }
13094
dchengb03027d2014-10-21 12:00:2013095 void PreconnectStreams(int num_streams,
13096 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2013097 const SSLConfig& server_ssl_config,
13098 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4713099 ADD_FAILURE();
13100 }
13101
dchengb03027d2014-10-21 12:00:2013102 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4713103 ADD_FAILURE();
13104 return NULL;
13105 }
13106
13107 private:
13108 base::WeakPtr<FakeStreamRequest> last_stream_request_;
13109
13110 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
13111};
13112
Adam Rice425cf122015-01-19 06:18:2413113// TODO(ricea): Maybe unify this with the one in
13114// url_request_http_job_unittest.cc ?
13115class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
13116 public:
13117 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
13118 bool using_proxy)
13119 : state_(connection.release(), using_proxy) {}
13120
13121 // Fake implementation of HttpStreamBase methods.
13122 // This ends up being quite "real" because this object has to really send data
13123 // on the mock socket. It might be easier to use the real implementation, but
13124 // the fact that the WebSocket code is not compiled on iOS makes that
13125 // difficult.
13126 int InitializeStream(const HttpRequestInfo* request_info,
13127 RequestPriority priority,
13128 const BoundNetLog& net_log,
13129 const CompletionCallback& callback) override {
13130 state_.Initialize(request_info, priority, net_log, callback);
13131 return OK;
13132 }
13133
13134 int SendRequest(const HttpRequestHeaders& request_headers,
13135 HttpResponseInfo* response,
13136 const CompletionCallback& callback) override {
13137 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
13138 response, callback);
13139 }
13140
13141 int ReadResponseHeaders(const CompletionCallback& callback) override {
13142 return parser()->ReadResponseHeaders(callback);
13143 }
13144
13145 int ReadResponseBody(IOBuffer* buf,
13146 int buf_len,
13147 const CompletionCallback& callback) override {
13148 NOTREACHED();
13149 return ERR_IO_PENDING;
13150 }
13151
13152 void Close(bool not_reusable) override {
13153 if (parser())
13154 parser()->Close(true);
13155 }
13156
13157 bool IsResponseBodyComplete() const override {
13158 NOTREACHED();
13159 return false;
13160 }
13161
13162 bool CanFindEndOfResponse() const override {
13163 return parser()->CanFindEndOfResponse();
13164 }
13165
13166 bool IsConnectionReused() const override {
13167 NOTREACHED();
13168 return false;
13169 }
13170 void SetConnectionReused() override { NOTREACHED(); }
13171
13172 bool IsConnectionReusable() const override {
13173 NOTREACHED();
13174 return false;
13175 }
13176
13177 int64 GetTotalReceivedBytes() const override {
13178 NOTREACHED();
13179 return 0;
13180 }
13181
13182 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13183 NOTREACHED();
13184 return false;
13185 }
13186
Adam Ricecb76ac62015-02-20 05:33:2513187 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413188
13189 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13190 NOTREACHED();
13191 }
13192
13193 bool IsSpdyHttpStream() const override {
13194 NOTREACHED();
13195 return false;
13196 }
13197
13198 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13199
13200 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13201
13202 UploadProgress GetUploadProgress() const override {
13203 NOTREACHED();
13204 return UploadProgress();
13205 }
13206
13207 HttpStream* RenewStreamForAuth() override {
13208 NOTREACHED();
13209 return nullptr;
13210 }
13211
13212 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13213 scoped_ptr<WebSocketStream> Upgrade() override {
13214 NOTREACHED();
13215 return scoped_ptr<WebSocketStream>();
13216 }
13217
13218 private:
13219 HttpStreamParser* parser() const { return state_.parser(); }
13220 HttpBasicState state_;
13221
13222 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13223};
13224
[email protected]831e4a32013-11-14 02:14:4413225// TODO(yhirano): Split this class out into a net/websockets file, if it is
13226// worth doing.
13227class FakeWebSocketStreamCreateHelper :
13228 public WebSocketHandshakeStreamBase::CreateHelper {
13229 public:
dchengb03027d2014-10-21 12:00:2013230 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113231 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313232 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413233 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13234 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413235 }
13236
dchengb03027d2014-10-21 12:00:2013237 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413238 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313239 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413240 NOTREACHED();
13241 return NULL;
13242 };
13243
dchengb03027d2014-10-21 12:00:2013244 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413245
13246 virtual scoped_ptr<WebSocketStream> Upgrade() {
13247 NOTREACHED();
13248 return scoped_ptr<WebSocketStream>();
13249 }
13250};
13251
[email protected]bf828982013-08-14 18:01:4713252} // namespace
13253
13254// Make sure that HttpNetworkTransaction passes on its priority to its
13255// stream request on start.
13256TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
13257 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13258 HttpNetworkSessionPeer peer(session);
13259 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413260 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713261
dcheng48459ac22014-08-26 00:46:4113262 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713263
13264 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13265
13266 HttpRequestInfo request;
13267 TestCompletionCallback callback;
13268 EXPECT_EQ(ERR_IO_PENDING,
13269 trans.Start(&request, callback.callback(), BoundNetLog()));
13270
13271 base::WeakPtr<FakeStreamRequest> fake_request =
13272 fake_factory->last_stream_request();
13273 ASSERT_TRUE(fake_request != NULL);
13274 EXPECT_EQ(LOW, fake_request->priority());
13275}
13276
13277// Make sure that HttpNetworkTransaction passes on its priority
13278// updates to its stream request.
13279TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
13280 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13281 HttpNetworkSessionPeer peer(session);
13282 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413283 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713284
dcheng48459ac22014-08-26 00:46:4113285 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713286
13287 HttpRequestInfo request;
13288 TestCompletionCallback callback;
13289 EXPECT_EQ(ERR_IO_PENDING,
13290 trans.Start(&request, callback.callback(), BoundNetLog()));
13291
13292 base::WeakPtr<FakeStreamRequest> fake_request =
13293 fake_factory->last_stream_request();
13294 ASSERT_TRUE(fake_request != NULL);
13295 EXPECT_EQ(LOW, fake_request->priority());
13296
13297 trans.SetPriority(LOWEST);
13298 ASSERT_TRUE(fake_request != NULL);
13299 EXPECT_EQ(LOWEST, fake_request->priority());
13300}
13301
[email protected]e86839fd2013-08-14 18:29:0313302// Make sure that HttpNetworkTransaction passes on its priority
13303// updates to its stream.
13304TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
13305 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13306 HttpNetworkSessionPeer peer(session);
13307 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413308 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313309
dcheng48459ac22014-08-26 00:46:4113310 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313311
13312 HttpRequestInfo request;
13313 TestCompletionCallback callback;
13314 EXPECT_EQ(ERR_IO_PENDING,
13315 trans.Start(&request, callback.callback(), BoundNetLog()));
13316
13317 base::WeakPtr<FakeStreamRequest> fake_request =
13318 fake_factory->last_stream_request();
13319 ASSERT_TRUE(fake_request != NULL);
13320 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13321 ASSERT_TRUE(fake_stream != NULL);
13322 EXPECT_EQ(LOW, fake_stream->priority());
13323
13324 trans.SetPriority(LOWEST);
13325 EXPECT_EQ(LOWEST, fake_stream->priority());
13326}
13327
[email protected]831e4a32013-11-14 02:14:4413328TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13329 // The same logic needs to be tested for both ws: and wss: schemes, but this
13330 // test is already parameterised on NextProto, so it uses a loop to verify
13331 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313332 std::string test_cases[] = {"ws://www.example.org/",
13333 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413334 for (size_t i = 0; i < arraysize(test_cases); ++i) {
13335 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13336 HttpNetworkSessionPeer peer(session);
13337 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13338 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313339 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413340 scoped_ptr<HttpStreamFactory>(fake_factory));
13341
dcheng48459ac22014-08-26 00:46:4113342 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413343 trans.SetWebSocketHandshakeStreamCreateHelper(
13344 &websocket_stream_create_helper);
13345
13346 HttpRequestInfo request;
13347 TestCompletionCallback callback;
13348 request.method = "GET";
13349 request.url = GURL(test_cases[i]);
13350
13351 EXPECT_EQ(ERR_IO_PENDING,
13352 trans.Start(&request, callback.callback(), BoundNetLog()));
13353
13354 base::WeakPtr<FakeStreamRequest> fake_request =
13355 fake_factory->last_stream_request();
13356 ASSERT_TRUE(fake_request != NULL);
13357 EXPECT_EQ(&websocket_stream_create_helper,
13358 fake_request->websocket_stream_create_helper());
13359 }
13360}
13361
[email protected]043b68c82013-08-22 23:41:5213362// Tests that when a used socket is returned to the SSL socket pool, it's closed
13363// if the transport socket pool is stalled on the global socket limit.
13364TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13365 ClientSocketPoolManager::set_max_sockets_per_group(
13366 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13367 ClientSocketPoolManager::set_max_sockets_per_pool(
13368 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13369
13370 // Set up SSL request.
13371
13372 HttpRequestInfo ssl_request;
13373 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313374 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213375
13376 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313377 MockWrite(
13378 "GET / HTTP/1.1\r\n"
13379 "Host: www.example.org\r\n"
13380 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213381 };
13382 MockRead ssl_reads[] = {
13383 MockRead("HTTP/1.1 200 OK\r\n"),
13384 MockRead("Content-Length: 11\r\n\r\n"),
13385 MockRead("hello world"),
13386 MockRead(SYNCHRONOUS, OK),
13387 };
13388 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13389 ssl_writes, arraysize(ssl_writes));
13390 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13391
13392 SSLSocketDataProvider ssl(ASYNC, OK);
13393 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13394
13395 // Set up HTTP request.
13396
13397 HttpRequestInfo http_request;
13398 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313399 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213400
13401 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313402 MockWrite(
13403 "GET / HTTP/1.1\r\n"
13404 "Host: www.example.org\r\n"
13405 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213406 };
13407 MockRead http_reads[] = {
13408 MockRead("HTTP/1.1 200 OK\r\n"),
13409 MockRead("Content-Length: 7\r\n\r\n"),
13410 MockRead("falafel"),
13411 MockRead(SYNCHRONOUS, OK),
13412 };
13413 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13414 http_writes, arraysize(http_writes));
13415 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13416
13417 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13418
13419 // Start the SSL request.
13420 TestCompletionCallback ssl_callback;
13421 scoped_ptr<HttpTransaction> ssl_trans(
13422 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13423 ASSERT_EQ(ERR_IO_PENDING,
13424 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13425 BoundNetLog()));
13426
13427 // Start the HTTP request. Pool should stall.
13428 TestCompletionCallback http_callback;
13429 scoped_ptr<HttpTransaction> http_trans(
13430 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13431 ASSERT_EQ(ERR_IO_PENDING,
13432 http_trans->Start(&http_request, http_callback.callback(),
13433 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113434 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213435
13436 // Wait for response from SSL request.
13437 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13438 std::string response_data;
13439 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13440 EXPECT_EQ("hello world", response_data);
13441
13442 // The SSL socket should automatically be closed, so the HTTP request can
13443 // start.
dcheng48459ac22014-08-26 00:46:4113444 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13445 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213446
13447 // The HTTP request can now complete.
13448 ASSERT_EQ(OK, http_callback.WaitForResult());
13449 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13450 EXPECT_EQ("falafel", response_data);
13451
dcheng48459ac22014-08-26 00:46:4113452 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213453}
13454
13455// Tests that when a SSL connection is established but there's no corresponding
13456// request that needs it, the new socket is closed if the transport socket pool
13457// is stalled on the global socket limit.
13458TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13459 ClientSocketPoolManager::set_max_sockets_per_group(
13460 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13461 ClientSocketPoolManager::set_max_sockets_per_pool(
13462 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13463
13464 // Set up an ssl request.
13465
13466 HttpRequestInfo ssl_request;
13467 ssl_request.method = "GET";
13468 ssl_request.url = GURL("https://www.foopy.com/");
13469
13470 // No data will be sent on the SSL socket.
13471 StaticSocketDataProvider ssl_data;
13472 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13473
13474 SSLSocketDataProvider ssl(ASYNC, OK);
13475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13476
13477 // Set up HTTP request.
13478
13479 HttpRequestInfo http_request;
13480 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313481 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213482
13483 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313484 MockWrite(
13485 "GET / HTTP/1.1\r\n"
13486 "Host: www.example.org\r\n"
13487 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213488 };
13489 MockRead http_reads[] = {
13490 MockRead("HTTP/1.1 200 OK\r\n"),
13491 MockRead("Content-Length: 7\r\n\r\n"),
13492 MockRead("falafel"),
13493 MockRead(SYNCHRONOUS, OK),
13494 };
13495 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13496 http_writes, arraysize(http_writes));
13497 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13498
13499 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13500
13501 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13502 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2913503 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13504 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5213505 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd2015-07-15 22:26:3513506 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
13507 ssl_config);
dcheng48459ac22014-08-26 00:46:4113508 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213509
13510 // Start the HTTP request. Pool should stall.
13511 TestCompletionCallback http_callback;
13512 scoped_ptr<HttpTransaction> http_trans(
13513 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13514 ASSERT_EQ(ERR_IO_PENDING,
13515 http_trans->Start(&http_request, http_callback.callback(),
13516 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113517 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213518
13519 // The SSL connection will automatically be closed once the connection is
13520 // established, to let the HTTP request start.
13521 ASSERT_EQ(OK, http_callback.WaitForResult());
13522 std::string response_data;
13523 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13524 EXPECT_EQ("falafel", response_data);
13525
dcheng48459ac22014-08-26 00:46:4113526 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213527}
13528
[email protected]02d74a02014-04-23 18:10:5413529TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13530 ScopedVector<UploadElementReader> element_readers;
13531 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713532 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413533
13534 HttpRequestInfo request;
13535 request.method = "POST";
13536 request.url = GURL("http://www.foo.com/");
13537 request.upload_data_stream = &upload_data_stream;
13538 request.load_flags = 0;
13539
13540 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13541 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113542 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413543 // Send headers successfully, but get an error while sending the body.
13544 MockWrite data_writes[] = {
13545 MockWrite("POST / HTTP/1.1\r\n"
13546 "Host: www.foo.com\r\n"
13547 "Connection: keep-alive\r\n"
13548 "Content-Length: 3\r\n\r\n"),
13549 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13550 };
13551
13552 MockRead data_reads[] = {
13553 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13554 MockRead("hello world"),
13555 MockRead(SYNCHRONOUS, OK),
13556 };
13557 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13558 arraysize(data_writes));
13559 session_deps_.socket_factory->AddSocketDataProvider(&data);
13560
13561 TestCompletionCallback callback;
13562
13563 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13564 EXPECT_EQ(ERR_IO_PENDING, rv);
13565
13566 rv = callback.WaitForResult();
13567 EXPECT_EQ(OK, rv);
13568
13569 const HttpResponseInfo* response = trans->GetResponseInfo();
13570 ASSERT_TRUE(response != NULL);
13571
13572 EXPECT_TRUE(response->headers.get() != NULL);
13573 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13574
13575 std::string response_data;
13576 rv = ReadTransaction(trans.get(), &response_data);
13577 EXPECT_EQ(OK, rv);
13578 EXPECT_EQ("hello world", response_data);
13579}
13580
13581// This test makes sure the retry logic doesn't trigger when reading an error
13582// response from a server that rejected a POST with a CONNECTION_RESET.
13583TEST_P(HttpNetworkTransactionTest,
13584 PostReadsErrorResponseAfterResetOnReusedSocket) {
13585 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13586 MockWrite data_writes[] = {
13587 MockWrite("GET / HTTP/1.1\r\n"
13588 "Host: www.foo.com\r\n"
13589 "Connection: keep-alive\r\n\r\n"),
13590 MockWrite("POST / HTTP/1.1\r\n"
13591 "Host: www.foo.com\r\n"
13592 "Connection: keep-alive\r\n"
13593 "Content-Length: 3\r\n\r\n"),
13594 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13595 };
13596
13597 MockRead data_reads[] = {
13598 MockRead("HTTP/1.1 200 Peachy\r\n"
13599 "Content-Length: 14\r\n\r\n"),
13600 MockRead("first response"),
13601 MockRead("HTTP/1.1 400 Not OK\r\n"
13602 "Content-Length: 15\r\n\r\n"),
13603 MockRead("second response"),
13604 MockRead(SYNCHRONOUS, OK),
13605 };
13606 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13607 arraysize(data_writes));
13608 session_deps_.socket_factory->AddSocketDataProvider(&data);
13609
13610 TestCompletionCallback callback;
13611 HttpRequestInfo request1;
13612 request1.method = "GET";
13613 request1.url = GURL("http://www.foo.com/");
13614 request1.load_flags = 0;
13615
13616 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4113617 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413618 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
13619 EXPECT_EQ(ERR_IO_PENDING, rv);
13620
13621 rv = callback.WaitForResult();
13622 EXPECT_EQ(OK, rv);
13623
13624 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13625 ASSERT_TRUE(response1 != NULL);
13626
13627 EXPECT_TRUE(response1->headers.get() != NULL);
13628 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
13629
13630 std::string response_data1;
13631 rv = ReadTransaction(trans1.get(), &response_data1);
13632 EXPECT_EQ(OK, rv);
13633 EXPECT_EQ("first response", response_data1);
13634 // Delete the transaction to release the socket back into the socket pool.
13635 trans1.reset();
13636
13637 ScopedVector<UploadElementReader> element_readers;
13638 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713639 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413640
13641 HttpRequestInfo request2;
13642 request2.method = "POST";
13643 request2.url = GURL("http://www.foo.com/");
13644 request2.upload_data_stream = &upload_data_stream;
13645 request2.load_flags = 0;
13646
13647 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4113648 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413649 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
13650 EXPECT_EQ(ERR_IO_PENDING, rv);
13651
13652 rv = callback.WaitForResult();
13653 EXPECT_EQ(OK, rv);
13654
13655 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
13656 ASSERT_TRUE(response2 != NULL);
13657
13658 EXPECT_TRUE(response2->headers.get() != NULL);
13659 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
13660
13661 std::string response_data2;
13662 rv = ReadTransaction(trans2.get(), &response_data2);
13663 EXPECT_EQ(OK, rv);
13664 EXPECT_EQ("second response", response_data2);
13665}
13666
13667TEST_P(HttpNetworkTransactionTest,
13668 PostReadsErrorResponseAfterResetPartialBodySent) {
13669 ScopedVector<UploadElementReader> element_readers;
13670 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713671 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413672
13673 HttpRequestInfo request;
13674 request.method = "POST";
13675 request.url = GURL("http://www.foo.com/");
13676 request.upload_data_stream = &upload_data_stream;
13677 request.load_flags = 0;
13678
13679 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13680 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113681 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413682 // Send headers successfully, but get an error while sending the body.
13683 MockWrite data_writes[] = {
13684 MockWrite("POST / HTTP/1.1\r\n"
13685 "Host: www.foo.com\r\n"
13686 "Connection: keep-alive\r\n"
13687 "Content-Length: 3\r\n\r\n"
13688 "fo"),
13689 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13690 };
13691
13692 MockRead data_reads[] = {
13693 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13694 MockRead("hello world"),
13695 MockRead(SYNCHRONOUS, OK),
13696 };
13697 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13698 arraysize(data_writes));
13699 session_deps_.socket_factory->AddSocketDataProvider(&data);
13700
13701 TestCompletionCallback callback;
13702
13703 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13704 EXPECT_EQ(ERR_IO_PENDING, rv);
13705
13706 rv = callback.WaitForResult();
13707 EXPECT_EQ(OK, rv);
13708
13709 const HttpResponseInfo* response = trans->GetResponseInfo();
13710 ASSERT_TRUE(response != NULL);
13711
13712 EXPECT_TRUE(response->headers.get() != NULL);
13713 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13714
13715 std::string response_data;
13716 rv = ReadTransaction(trans.get(), &response_data);
13717 EXPECT_EQ(OK, rv);
13718 EXPECT_EQ("hello world", response_data);
13719}
13720
13721// This tests the more common case than the previous test, where headers and
13722// body are not merged into a single request.
13723TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
13724 ScopedVector<UploadElementReader> element_readers;
13725 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713726 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5413727
13728 HttpRequestInfo request;
13729 request.method = "POST";
13730 request.url = GURL("http://www.foo.com/");
13731 request.upload_data_stream = &upload_data_stream;
13732 request.load_flags = 0;
13733
13734 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13735 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113736 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413737 // Send headers successfully, but get an error while sending the body.
13738 MockWrite data_writes[] = {
13739 MockWrite("POST / HTTP/1.1\r\n"
13740 "Host: www.foo.com\r\n"
13741 "Connection: keep-alive\r\n"
13742 "Transfer-Encoding: chunked\r\n\r\n"),
13743 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13744 };
13745
13746 MockRead data_reads[] = {
13747 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13748 MockRead("hello world"),
13749 MockRead(SYNCHRONOUS, OK),
13750 };
13751 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13752 arraysize(data_writes));
13753 session_deps_.socket_factory->AddSocketDataProvider(&data);
13754
13755 TestCompletionCallback callback;
13756
13757 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13758 EXPECT_EQ(ERR_IO_PENDING, rv);
13759 // Make sure the headers are sent before adding a chunk. This ensures that
13760 // they can't be merged with the body in a single send. Not currently
13761 // necessary since a chunked body is never merged with headers, but this makes
13762 // the test more future proof.
13763 base::RunLoop().RunUntilIdle();
13764
mmenkecbc2b712014-10-09 20:29:0713765 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5413766
13767 rv = callback.WaitForResult();
13768 EXPECT_EQ(OK, rv);
13769
13770 const HttpResponseInfo* response = trans->GetResponseInfo();
13771 ASSERT_TRUE(response != NULL);
13772
13773 EXPECT_TRUE(response->headers.get() != NULL);
13774 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13775
13776 std::string response_data;
13777 rv = ReadTransaction(trans.get(), &response_data);
13778 EXPECT_EQ(OK, rv);
13779 EXPECT_EQ("hello world", response_data);
13780}
13781
13782TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
13783 ScopedVector<UploadElementReader> element_readers;
13784 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713785 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413786
13787 HttpRequestInfo request;
13788 request.method = "POST";
13789 request.url = GURL("http://www.foo.com/");
13790 request.upload_data_stream = &upload_data_stream;
13791 request.load_flags = 0;
13792
13793 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13794 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113795 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413796
13797 MockWrite data_writes[] = {
13798 MockWrite("POST / HTTP/1.1\r\n"
13799 "Host: www.foo.com\r\n"
13800 "Connection: keep-alive\r\n"
13801 "Content-Length: 3\r\n\r\n"),
13802 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13803 };
13804
13805 MockRead data_reads[] = {
13806 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13807 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13808 MockRead("hello world"),
13809 MockRead(SYNCHRONOUS, OK),
13810 };
13811 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13812 arraysize(data_writes));
13813 session_deps_.socket_factory->AddSocketDataProvider(&data);
13814
13815 TestCompletionCallback callback;
13816
13817 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13818 EXPECT_EQ(ERR_IO_PENDING, rv);
13819
13820 rv = callback.WaitForResult();
13821 EXPECT_EQ(OK, rv);
13822
13823 const HttpResponseInfo* response = trans->GetResponseInfo();
13824 ASSERT_TRUE(response != NULL);
13825
13826 EXPECT_TRUE(response->headers.get() != NULL);
13827 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13828
13829 std::string response_data;
13830 rv = ReadTransaction(trans.get(), &response_data);
13831 EXPECT_EQ(OK, rv);
13832 EXPECT_EQ("hello world", response_data);
13833}
13834
13835TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
13836 ScopedVector<UploadElementReader> element_readers;
13837 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713838 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413839
13840 HttpRequestInfo request;
13841 request.method = "POST";
13842 request.url = GURL("http://www.foo.com/");
13843 request.upload_data_stream = &upload_data_stream;
13844 request.load_flags = 0;
13845
13846 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13847 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113848 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413849 // Send headers successfully, but get an error while sending the body.
13850 MockWrite data_writes[] = {
13851 MockWrite("POST / HTTP/1.1\r\n"
13852 "Host: www.foo.com\r\n"
13853 "Connection: keep-alive\r\n"
13854 "Content-Length: 3\r\n\r\n"),
13855 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13856 };
13857
13858 MockRead data_reads[] = {
13859 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
13860 MockRead("hello world"),
13861 MockRead(SYNCHRONOUS, OK),
13862 };
13863 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13864 arraysize(data_writes));
13865 session_deps_.socket_factory->AddSocketDataProvider(&data);
13866
13867 TestCompletionCallback callback;
13868
13869 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13870 EXPECT_EQ(ERR_IO_PENDING, rv);
13871
13872 rv = callback.WaitForResult();
13873 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413874}
13875
13876TEST_P(HttpNetworkTransactionTest,
13877 PostIgnoresNonErrorResponseAfterResetAnd100) {
13878 ScopedVector<UploadElementReader> element_readers;
13879 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713880 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413881
13882 HttpRequestInfo request;
13883 request.method = "POST";
13884 request.url = GURL("http://www.foo.com/");
13885 request.upload_data_stream = &upload_data_stream;
13886 request.load_flags = 0;
13887
13888 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13889 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113890 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413891 // Send headers successfully, but get an error while sending the body.
13892 MockWrite data_writes[] = {
13893 MockWrite("POST / HTTP/1.1\r\n"
13894 "Host: www.foo.com\r\n"
13895 "Connection: keep-alive\r\n"
13896 "Content-Length: 3\r\n\r\n"),
13897 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13898 };
13899
13900 MockRead data_reads[] = {
13901 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
13902 MockRead("HTTP/1.0 302 Redirect\r\n"),
13903 MockRead("Location: http://somewhere-else.com/\r\n"),
13904 MockRead("Content-Length: 0\r\n\r\n"),
13905 MockRead(SYNCHRONOUS, OK),
13906 };
13907 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13908 arraysize(data_writes));
13909 session_deps_.socket_factory->AddSocketDataProvider(&data);
13910
13911 TestCompletionCallback callback;
13912
13913 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13914 EXPECT_EQ(ERR_IO_PENDING, rv);
13915
13916 rv = callback.WaitForResult();
13917 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413918}
13919
13920TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
13921 ScopedVector<UploadElementReader> element_readers;
13922 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713923 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413924
13925 HttpRequestInfo request;
13926 request.method = "POST";
13927 request.url = GURL("http://www.foo.com/");
13928 request.upload_data_stream = &upload_data_stream;
13929 request.load_flags = 0;
13930
13931 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13932 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113933 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413934 // Send headers successfully, but get an error while sending the body.
13935 MockWrite data_writes[] = {
13936 MockWrite("POST / HTTP/1.1\r\n"
13937 "Host: www.foo.com\r\n"
13938 "Connection: keep-alive\r\n"
13939 "Content-Length: 3\r\n\r\n"),
13940 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13941 };
13942
13943 MockRead data_reads[] = {
13944 MockRead("HTTP 0.9 rocks!"),
13945 MockRead(SYNCHRONOUS, OK),
13946 };
13947 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13948 arraysize(data_writes));
13949 session_deps_.socket_factory->AddSocketDataProvider(&data);
13950
13951 TestCompletionCallback callback;
13952
13953 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13954 EXPECT_EQ(ERR_IO_PENDING, rv);
13955
13956 rv = callback.WaitForResult();
13957 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413958}
13959
13960TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
13961 ScopedVector<UploadElementReader> element_readers;
13962 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713963 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413964
13965 HttpRequestInfo request;
13966 request.method = "POST";
13967 request.url = GURL("http://www.foo.com/");
13968 request.upload_data_stream = &upload_data_stream;
13969 request.load_flags = 0;
13970
13971 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13972 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113973 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413974 // Send headers successfully, but get an error while sending the body.
13975 MockWrite data_writes[] = {
13976 MockWrite("POST / HTTP/1.1\r\n"
13977 "Host: www.foo.com\r\n"
13978 "Connection: keep-alive\r\n"
13979 "Content-Length: 3\r\n\r\n"),
13980 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13981 };
13982
13983 MockRead data_reads[] = {
13984 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
13985 MockRead(SYNCHRONOUS, OK),
13986 };
13987 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13988 arraysize(data_writes));
13989 session_deps_.socket_factory->AddSocketDataProvider(&data);
13990
13991 TestCompletionCallback callback;
13992
13993 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13994 EXPECT_EQ(ERR_IO_PENDING, rv);
13995
13996 rv = callback.WaitForResult();
13997 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5413998}
13999
Adam Rice425cf122015-01-19 06:18:2414000// Verify that proxy headers are not sent to the destination server when
14001// establishing a tunnel for a secure WebSocket connection.
14002TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
14003 HttpRequestInfo request;
14004 request.method = "GET";
bncce36dca22015-04-21 22:11:2314005 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414006 AddWebSocketHeaders(&request.extra_headers);
14007
14008 // Configure against proxy server "myproxy:70".
14009 session_deps_.proxy_service.reset(
14010 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14011
14012 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14013
14014 // Since a proxy is configured, try to establish a tunnel.
14015 MockWrite data_writes[] = {
14016 MockWrite(
bncce36dca22015-04-21 22:11:2314017 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14018 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414019 "Proxy-Connection: keep-alive\r\n\r\n"),
14020
14021 // After calling trans->RestartWithAuth(), this is the request we should
14022 // be issuing -- the final header line contains the credentials.
14023 MockWrite(
bncce36dca22015-04-21 22:11:2314024 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14025 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414026 "Proxy-Connection: keep-alive\r\n"
14027 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14028
14029 MockWrite(
14030 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314031 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414032 "Connection: Upgrade\r\n"
14033 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314034 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414035 "Sec-WebSocket-Version: 13\r\n"
14036 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14037 };
14038
14039 // The proxy responds to the connect with a 407, using a persistent
14040 // connection.
14041 MockRead data_reads[] = {
14042 // No credentials.
14043 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14044 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
14045 MockRead("Proxy-Connection: close\r\n\r\n"),
14046
14047 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14048
14049 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14050 MockRead("Upgrade: websocket\r\n"),
14051 MockRead("Connection: Upgrade\r\n"),
14052 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14053 };
14054
14055 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14056 arraysize(data_writes));
14057 session_deps_.socket_factory->AddSocketDataProvider(&data);
14058 SSLSocketDataProvider ssl(ASYNC, OK);
14059 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14060
14061 scoped_ptr<HttpTransaction> trans(
14062 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14063 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14064 trans->SetWebSocketHandshakeStreamCreateHelper(
14065 &websocket_stream_create_helper);
14066
14067 {
14068 TestCompletionCallback callback;
14069
14070 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14071 EXPECT_EQ(ERR_IO_PENDING, rv);
14072
14073 rv = callback.WaitForResult();
14074 EXPECT_EQ(OK, rv);
14075 }
14076
14077 const HttpResponseInfo* response = trans->GetResponseInfo();
14078 ASSERT_TRUE(response);
14079 ASSERT_TRUE(response->headers.get());
14080 EXPECT_EQ(407, response->headers->response_code());
14081
14082 {
14083 TestCompletionCallback callback;
14084
14085 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
14086 callback.callback());
14087 EXPECT_EQ(ERR_IO_PENDING, rv);
14088
14089 rv = callback.WaitForResult();
14090 EXPECT_EQ(OK, rv);
14091 }
14092
14093 response = trans->GetResponseInfo();
14094 ASSERT_TRUE(response);
14095 ASSERT_TRUE(response->headers.get());
14096
14097 EXPECT_EQ(101, response->headers->response_code());
14098
14099 trans.reset();
14100 session->CloseAllConnections();
14101}
14102
14103// Verify that proxy headers are not sent to the destination server when
14104// establishing a tunnel for an insecure WebSocket connection.
14105// This requires the authentication info to be injected into the auth cache
14106// due to crbug.com/395064
14107// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
14108TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
14109 HttpRequestInfo request;
14110 request.method = "GET";
bncce36dca22015-04-21 22:11:2314111 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414112 AddWebSocketHeaders(&request.extra_headers);
14113
14114 // Configure against proxy server "myproxy:70".
14115 session_deps_.proxy_service.reset(
14116 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14117
14118 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14119
14120 MockWrite data_writes[] = {
14121 // Try to establish a tunnel for the WebSocket connection, with
14122 // credentials. Because WebSockets have a separate set of socket pools,
14123 // they cannot and will not use the same TCP/IP connection as the
14124 // preflight HTTP request.
14125 MockWrite(
bncce36dca22015-04-21 22:11:2314126 "CONNECT www.example.org:80 HTTP/1.1\r\n"
14127 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2414128 "Proxy-Connection: keep-alive\r\n"
14129 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14130
14131 MockWrite(
14132 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314133 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414134 "Connection: Upgrade\r\n"
14135 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314136 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414137 "Sec-WebSocket-Version: 13\r\n"
14138 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14139 };
14140
14141 MockRead data_reads[] = {
14142 // HTTP CONNECT with credentials.
14143 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14144
14145 // WebSocket connection established inside tunnel.
14146 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14147 MockRead("Upgrade: websocket\r\n"),
14148 MockRead("Connection: Upgrade\r\n"),
14149 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14150 };
14151
14152 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14153 arraysize(data_writes));
14154 session_deps_.socket_factory->AddSocketDataProvider(&data);
14155
14156 session->http_auth_cache()->Add(
14157 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
14158 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
14159
14160 scoped_ptr<HttpTransaction> trans(
14161 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14162 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14163 trans->SetWebSocketHandshakeStreamCreateHelper(
14164 &websocket_stream_create_helper);
14165
14166 TestCompletionCallback callback;
14167
14168 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14169 EXPECT_EQ(ERR_IO_PENDING, rv);
14170
14171 rv = callback.WaitForResult();
14172 EXPECT_EQ(OK, rv);
14173
14174 const HttpResponseInfo* response = trans->GetResponseInfo();
14175 ASSERT_TRUE(response);
14176 ASSERT_TRUE(response->headers.get());
14177
14178 EXPECT_EQ(101, response->headers->response_code());
14179
14180 trans.reset();
14181 session->CloseAllConnections();
14182}
14183
[email protected]89ceba9a2009-03-21 03:46:0614184} // namespace net